Now, here's the challenge:
The micro has only 8 pins, and the SAO connector has 6 and there are limitations to the configuration of the pins, and the functions they support, so the right choices here are critical.
I need the following:
- VCC & GND
- A regular GPIO for pushbutton input
- SDA and SDC for I2C input
- SPI MOSI to drive the RGB LEDs
- Retain the SWDIO and SWCLK for programming/debugging.
This took equal parts planning and experimentation, with one layout revision and re-routing the board, but I was able to make it work. The key to this success was changing Pin 6 NRST function to a regular GPIO, and this is achieved by setting some user options in the flash. Again, I relied on a HAL example to get this to work, and the SAO will check the mode on boot up and set the flash if it needs to then reboot - this is completely reversible by changing a define in the code and recompiling, so I didn't brick any of my $0.12 chips :)
This is the magic bit of code that makes it possible and the first thing that happens in the main() function.
HAL_Init();
/* Check RST pin mode */
#if defined(RSTPIN_MODE_GPIO)
if( READ_BIT(FLASH->OPTR, FLASH_OPTR_NRST_MODE) == OB_RESET_MODE_RESET)
#else
if( READ_BIT(FLASH->OPTR, FLASH_OPTR_NRST_MODE) == OB_RESET_MODE_GPIO)
#endif
{
// program option byte
HAL_FLASH_Unlock(); /* Unlock FLASH */
HAL_FLASH_OB_Unlock(); /* Unlock OPTION */
FLASH_OBProgramInitTypeDef OBInitCfg = {0};
/* Configure OPTION settings */
OBInitCfg.OptionType = OPTIONBYTE_USER;
OBInitCfg.USERType = OB_USER_BOR_EN | OB_USER_BOR_LEV | OB_USER_IWDG_SW | OB_USER_NRST_MODE | OB_USER_nBOOT1;
#if defined(RSTPIN_MODE_GPIO)
/* Disable BOR/Enable BOR rising 3.2V, falling 3.1V/Software watchdog mode/GPIO functionality/System memory as boot area */
OBInitCfg.USERConfig = OB_BOR_DISABLE | OB_BOR_LEVEL_3p1_3p2 | OB_IWDG_SW | OB_RESET_MODE_GPIO | OB_BOOT1_SYSTEM;
#else
/* Disable BOR/Enable BOR rising 3.2V, falling 3.1V/Software watchdog mode/RST functionality/System memory as boot area */
OBInitCfg.USERConfig = OB_BOR_DISABLE | OB_BOR_LEVEL_3p1_3p2 | OB_IWDG_SW | OB_RESET_MODE_RESET | OB_BOOT1_SYSTEM;
#endif
/* Start option byte programming */
HAL_FLASH_OBProgram(&OBInitCfg);
HAL_FLASH_Lock(); /* Lock FLASH */
HAL_FLASH_OB_Lock(); /* Lock OPTION */
/* Generate a reset to load the option bytes */
HAL_FLASH_OB_Launch();
}
This means I can then go on to use Pin 6 (PA2) in it's alternate function mode as I2C SDA.
The final pin configuration I used is as follows.
Pin Name | Function | SAO Header | |
---|---|---|---|
1 | Vcc | Power in | VCC |
2 | PA4/PA10 | I2C SCL (alternate function) | SCL |
3 | PA3 | SPI MOSI (LED driver) | N/A |
4 | PA14-SWC/PB3 | SWCLK (for programming/debugging) | GPIO2 |
5 | PA13-SWD | SWDIO | GPIO1 |
6 | PA2/PF2 | I2C SDA | SDA |
7 | PA1 | GPIO pushbutton input | N/A |
8 | Vss | Ground | GND |
This configuration theoretically means you could make a SWD compatiple programmer from your badge and re-program the SAO from it.
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.