Skip to content

Commit 936aebe

Browse files
committed
feat: Assemble / show full POST codes on display
1 parent 6782cc1 commit 936aebe

4 files changed

Lines changed: 130 additions & 35 deletions

File tree

firmware/userapp/Core/Inc/display.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ extern I2C_HandleTypeDef hi2c2;
1515
void Display_Init(void);
1616
void Display_Print(const char *message);
1717
void Display_ScrollText(const char *text);
18-
void Display_ShowCode(uint16_t code, uint8_t segment);
18+
void Display_ShowCode(uint64_t code, const char *flavor);
1919
void Display_Tick(void);
2020

2121
#ifdef __cplusplus

firmware/userapp/Core/Inc/postcodes.h

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ extern "C" {
88
#include "main.h"
99
#include "slave.h"
1010

11+
#define SEGMENT_FLAVOR_MASK 0xF0
12+
#define SEGMENT_INDEX_MASK 0x0F
13+
1114
// Indicated by Segments-register
1215
enum CodeFlavor: uint8_t {
1316
CODE_FLAVOR_CPU = 0x10,
@@ -16,6 +19,11 @@ enum CodeFlavor: uint8_t {
1619
CODE_FLAVOR_OS = 0xF0,
1720
};
1821

22+
typedef struct {
23+
uint64_t code;
24+
uint8_t flavor;
25+
} PostCode;
26+
1927
enum MAX6958Registers {
2028
REG_NoOp = 0x00,
2129
REG_DecodeMode = 0x01,
@@ -34,10 +42,13 @@ enum MAX6958Registers {
3442
REG_Segments = 0x24,
3543
};
3644

37-
uint16_t POST_ReadCode();
38-
uint8_t POST_ReadSegment();
39-
const char *POST_GetSegmentName(uint8_t seg);
40-
char POST_GetSegmentIndex(uint8_t seg);
45+
const char *POST_GetSegmentName(uint8_t flavor);
46+
47+
// Feeds the current Digit0-3/Segments registers into the code assembler.
48+
// A full POST code is made up of up to 4 consecutive Segments-writes of the
49+
// same flavor (MSB-first, terminated by index 1); returns 1 and fills *out
50+
// once a full code has been assembled, 0 otherwise.
51+
uint8_t POST_ProcessSegment(PostCode *out);
4152

4253
#ifdef __cplusplus
4354
}

firmware/userapp/Core/Src/display.c

Lines changed: 40 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@
1111
static u8g2_t myDisplay;
1212

1313
static char lcd_buf[20] = {0};
14-
static const char *seg_name = NULL;
15-
static char seg_index_str[] = {'(', 'X', ')' ,'\0'};
1614

1715
uint8_t u8x8_gpio_and_delay(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
1816
{
@@ -136,20 +134,45 @@ void Display_Init(void)
136134
u8g2_ClearDisplay(&myDisplay);
137135
}
138136

139-
void Display_ShowCode(uint16_t code, uint8_t segment) {
140-
seg_name = POST_GetSegmentName(segment);
141-
// Convert numeric index to ASCII character
142-
seg_index_str[1] = POST_GetSegmentIndex(segment) + '0';
137+
static void drawCenteredStr(int16_t y, const char *str) {
138+
int16_t x = (64 - u8g2_GetStrWidth(&myDisplay, str)) / 2;
139+
if (x < 0) {
140+
x = 0;
141+
}
142+
u8g2_DrawStr(&myDisplay, x, y, str);
143+
}
143144

144-
// Assemble content
145-
snprintf(lcd_buf, sizeof(lcd_buf), "%04X", code);
145+
void Display_ShowCode(uint64_t code, const char *flavor) {
146+
// Unpadded hex digit count, to decide layout below.
147+
uint64_t tmp = code;
148+
int digits = 1;
149+
while (tmp > 0xF) {
150+
tmp >>= 4;
151+
digits++;
152+
}
146153

147154
u8g2_ClearDisplay(&myDisplay);
148-
u8g2_SetFont(&myDisplay, u8g2_font_luBS14_tr);
149-
u8g2_DrawStr(&myDisplay, 4, 32, lcd_buf);
150-
u8g2_SetFont(&myDisplay, u8g2_font_7x13_mr);
151-
u8g2_DrawStr(&myDisplay, 12, 10, seg_name);
152-
u8g2_DrawStr(&myDisplay, 40, 10, seg_index_str);
155+
156+
u8g2_SetFont(&myDisplay, u8g2_font_5x7_mr);
157+
u8g2_DrawStr(&myDisplay, 2, 7, flavor);
158+
159+
if (digits <= 8) {
160+
// Fits in 32 bits: single, bigger line.
161+
char buf[9];
162+
snprintf(buf, sizeof(buf), "%lX", (unsigned long)code);
163+
u8g2_SetFont(&myDisplay, u8g2_font_7x13_mr);
164+
drawCenteredStr(30, buf);
165+
} else {
166+
// Longer code: split across two lines, one 32-bit half each.
167+
char hiBuf[9];
168+
char loBuf[9];
169+
snprintf(hiBuf, sizeof(hiBuf), "%lX", (unsigned long)(code >> 32));
170+
snprintf(loBuf, sizeof(loBuf), "%lX", (unsigned long)code);
171+
u8g2_SetFont(&myDisplay, u8g2_font_6x10_mr);
172+
drawCenteredStr(18, hiBuf);
173+
drawCenteredStr(29, loBuf);
174+
}
175+
153176
u8g2_SendBuffer(&myDisplay);
154177
}
155178

@@ -160,13 +183,12 @@ void Display_ShowCode(uint16_t code, uint8_t segment) {
160183
*/
161184
void Display_Tick(void)
162185
{
186+
PostCode postCode;
187+
163188
if (Slave_HardError()) {
164189
Display_Print("BUS ERROR");
165-
} else if (Slave_IsNewSegmentAvailable()) {
166-
Display_ShowCode(
167-
POST_ReadCode(),
168-
POST_ReadSegment()
169-
);
190+
} else if (Slave_IsNewSegmentAvailable() && POST_ProcessSegment(&postCode)) {
191+
Display_ShowCode(postCode.code, POST_GetSegmentName(postCode.flavor));
170192
} else if (Button_IsPressed()) {
171193
Display_Print("BtnPress");
172194
}
Lines changed: 74 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,33 @@
11
#include "postcodes.h"
22

3-
uint16_t POST_ReadCode() {
4-
return (Slave_RegRead(REG_Digit0) & 0x0F)
5-
| ((Slave_RegRead(REG_Digit1) & 0x0F) << 4)
6-
| ((Slave_RegRead(REG_Digit2) & 0x0F) << 8)
7-
| ((Slave_RegRead(REG_Digit3) & 0x0F) << 12);
3+
#define POST_CODE_WORD_COUNT 4
4+
5+
static uint16_t codeWords[POST_CODE_WORD_COUNT] = {0};
6+
static uint8_t currFlavor = 0;
7+
static uint8_t currIndex = 0; // 0 == no pending accumulation
8+
// Set when a blank (index 0) Segments-write of the same flavor as the
9+
// pending accumulation is observed; consumed by the next real segment to
10+
// prove it's a genuine continuation rather than an unrelated/abandoned one.
11+
static uint8_t sawContinuationMarker = 0;
12+
13+
static void resetCodeWords(void) {
14+
for (int i = 0; i < POST_CODE_WORD_COUNT; i++) {
15+
codeWords[i] = 0;
16+
}
17+
currIndex = 0;
18+
sawContinuationMarker = 0;
819
}
920

10-
uint8_t POST_ReadSegment() {
11-
return Slave_RegRead(REG_Segments);
21+
static uint64_t assembleCode(void) {
22+
uint64_t code = 0;
23+
for (int i = 0; i < POST_CODE_WORD_COUNT; i++) {
24+
code |= (uint64_t)codeWords[i] << (16 * i);
25+
}
26+
return code;
1227
}
1328

14-
const char *POST_GetSegmentName(uint8_t seg) {
15-
switch (seg & 0xF0) {
29+
const char *POST_GetSegmentName(uint8_t flavor) {
30+
switch (flavor & SEGMENT_FLAVOR_MASK) {
1631
case CODE_FLAVOR_CPU:
1732
return "CPU";
1833
case CODE_FLAVOR_SP:
@@ -26,6 +41,53 @@ const char *POST_GetSegmentName(uint8_t seg) {
2641
}
2742
}
2843

29-
char POST_GetSegmentIndex(uint8_t seg) {
30-
return seg & 0x0F;
31-
}
44+
uint8_t POST_ProcessSegment(PostCode *out) {
45+
uint8_t segByte = Slave_RegRead(REG_Segments);
46+
uint8_t flavor = segByte & SEGMENT_FLAVOR_MASK;
47+
uint8_t rawIndex = segByte & SEGMENT_INDEX_MASK;
48+
49+
if (rawIndex == 0) {
50+
// Blank write: no digit data, but the console sends it between
51+
// every part of a genuine multi-part code tagged with that code's flavor.
52+
if (currIndex != 0 && flavor == currFlavor) {
53+
sawContinuationMarker = 1;
54+
}
55+
return 0;
56+
}
57+
58+
uint8_t code_idx;
59+
switch (rawIndex) {
60+
case 1: code_idx = 0; break;
61+
case 2: code_idx = 1; break;
62+
case 4: code_idx = 2; break;
63+
case 8: code_idx = 3; break;
64+
default: return 0;
65+
}
66+
67+
uint8_t isContinuation = currIndex != 0 && sawContinuationMarker && flavor == currFlavor;
68+
if (currIndex != 0 && !isContinuation) {
69+
// Pending accumulation was never continued (no matching blank
70+
// marker seen); discard it instead of merging stale digits into
71+
// this segment.
72+
resetCodeWords();
73+
}
74+
75+
codeWords[code_idx] = (Slave_RegRead(REG_Digit0) & 0x0F)
76+
| ((Slave_RegRead(REG_Digit1) & 0x0F) << 4)
77+
| ((Slave_RegRead(REG_Digit2) & 0x0F) << 8)
78+
| ((Slave_RegRead(REG_Digit3) & 0x0F) << 12);
79+
currFlavor = flavor;
80+
currIndex = rawIndex;
81+
sawContinuationMarker = 0;
82+
83+
// Codes come in MSB-first (index order: 8, 4, 2, 1)
84+
// When index is 1, full code was transmitted from console
85+
if (rawIndex != 1) {
86+
return 0;
87+
}
88+
89+
out->code = assembleCode();
90+
out->flavor = currFlavor;
91+
resetCodeWords();
92+
return 1;
93+
}

0 commit comments

Comments
 (0)