Bringing up Corntroller

I compen­sate for my engi­neer­ing mistakes with bigger engi­neer­ing mistakes. -Me

Every new board needs an “LED blink” program. It’s basi­cally a Hello, world! for embed­ded engi­neers. Thing is, I put two seven-segment LED arrays on Corn­troller, my brush­less motor controller, so my LED blink program got a little bit fan-çay:

The displays were the first things I wanted to program anyways (USB is next). Among other things, you can display hexa­dec­i­mal digits on them, which is pretty straight­for­ward from a code perspec­tive:

static struct SevenSegmentDisplay {
public:
	SevenSegmentDisplay(GPIO_TypeDef *gpio, uint8_t offset) :
			gpio(gpio), offset(offset) {
	}

	void showHex(uint8_t x) {
		palClearPort(gpio, 0xF7 << offset);
		palSetPort(gpio, charLUT[x % 16] << offset);
	}

	void setDP(bool dp) {
		palWritePad(gpio, offset + 3, dp);
	}

protected:
	GPIO_TypeDef * const gpio;
	const uint8_t offset;

	static const uint8_t charLUT[16];
} red(GPIOD, 8), green(GPIOE, 0);

const uint8_t SevenSegmentDisplay::charLUT[16] = {
		0x77, 0x14, 0xB3, 0xB6,
		0xD4, 0xE6, 0xE7, 0x34,
		0xF7, 0xF6, 0xF5, 0xC7,
		0x63, 0x97, 0xE3, 0xE1
};

Making that lookup table was the hard­est part. Most code is writ­ten for “abcdefg” bit order, but my LEDs were bit-swiz­zled since I rearranged my lines to have a cleaner layout. This just meant I needed differ­ent bit patterns:

// - GFABPCDE
// 0 01110111
// 1 00010100
// 2 10110011
// 3 10110110
// 4 11010100
// 5 11100110
// 6 11100111
// 7 00110100
// 8 11110111
// 9 11110110
// A 11110101
// b 11000111
// C 01100011
// d 10010111
// E 11100011
// F 11100001

For a clean layout, it’s totally worth it.