Bringing up Corntroller

I com­pen­sate for my engi­neer­ing mis­takes with big­ger engi­neer­ing mis­takes. -Me

Every new board needs an “LED blink” pro­gram. It’s basi­cal­ly a Hel­lo, world! for embed­ded engi­neers. Thing is, I put two sev­en-seg­ment LED arrays on Corn­troller, my brush­less motor con­troller, so my LED blink pro­gram got a lit­tle bit fan-çay:

The dis­plays were the first things I want­ed to pro­gram any­ways (USB is next). Among oth­er things, you can dis­play hexa­dec­i­mal dig­its on them, which is pret­ty straight­for­ward from a code per­spec­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
};

Mak­ing that lookup table was the hard­est part. Most code is writ­ten for “abcde­fg” bit order, but my LEDs were bit-swiz­zled since I rearranged my lines to have a clean­er lay­out. This just meant I need­ed dif­fer­ent bit pat­terns:

// - 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 lay­out, it’s total­ly worth it.