Close

Perfecting the pinout

A project log for Hack-Man SAO

A Pac-Man themed SAO using an obscure but cheap microcontroller

instantarcade-bobInstantArcade (Bob) 10/07/2024 at 04:440 Comments

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:

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
FunctionSAO Header
1
Vcc
Power in
VCC
2PA4/PA10I2C SCL (alternate function)
SCL
3PA3SPI MOSI (LED driver)
N/A
4PA14-SWC/PB3SWCLK (for programming/debugging)
GPIO2
5PA13-SWDSWDIO
GPIO1
6PA2/PF2I2C SDA
SDA
7PA1GPIO pushbutton input
N/A
8VssGroundGND

This configuration theoretically means you could make a SWD compatiple programmer from your badge and re-program the SAO from it.

Discussions