From a06d8de78c6ce3fce50f5df4cd2fad2058bbd4a3 Mon Sep 17 00:00:00 2001 From: Tharo <17233964+Thar0@users.noreply.github.com> Date: Thu, 28 Nov 2024 17:37:02 +0000 Subject: [PATCH] [iQue] Decompile errorled.c, GPIO register defines (#74) * Decompile errorled.c, GPIO register defines * LED_OFF <-> LED_ON * RTC doc * Correct GPIO --- include/PR/bcp.h | 56 +++++++++++++++++-- src/bb/misc/boxid.c | 2 +- src/bb/misc/errorled.c | 14 +++++ src/bb/misc/power.c | 6 +- src/bb/misc/rtc.c | 124 +++++++++++++++++++++++++++++------------ src/os/initialize.c | 2 +- 6 files changed, 159 insertions(+), 45 deletions(-) create mode 100644 src/bb/misc/errorled.c diff --git a/include/PR/bcp.h b/include/PR/bcp.h index ade290c4..3bc63435 100644 --- a/include/PR/bcp.h +++ b/include/PR/bcp.h @@ -70,10 +70,58 @@ //! ? #define PI_5C_REG (PI_BASE_REG + 0x5C) - - -//! PI_MISC_REG ? -#define PI_60_REG (PI_BASE_REG + 0x60) +/** + * [31:16] Box ID + * [31:30] ?? (osInitialize checks this and sets __osBbIsBb to 2 if != 0) + * [29:27] ?? (unused so far) + * [26:25] ?? (system clock speed identifier?) + * [24:22] ?? (bootrom, checked against MI_10_REG and copied there if mismatch) + * [21:16] ?? (unused so far) + * [ 7: 4] GPIO direction control + * [7] RTC Data output enable + * [6] RTC Clock output enable + * [5] Error LED output enable + * [4] Power Control output enable + * [ 3: 0] GPIO in/out value + * [3] RTC Data output value (0=low, 1=high) + * [2] RTC Clock output value (0=low, 1=high) + * [1] Error LED (0=on, 1=off) + * [0] Power Control (0=off, 1=on) + */ +#define PI_GPIO_REG (PI_BASE_REG + 0x60) + +/* Box ID */ +#define PI_GPIO_GET_BOXID(reg) ((reg) >> 16) +#define PI_GPIO_BOXID_MASK_30_31 (3 << 30) + +/* Input/Output enables */ +#define PI_GPIO_I_PWR ((0 << 0) << 4) +#define PI_GPIO_O_PWR ((1 << 0) << 4) +#define PI_GPIO_I_LED ((0 << 1) << 4) +#define PI_GPIO_O_LED ((1 << 1) << 4) +#define PI_GPIO_I_RTC_CLK ((0 << 2) << 4) +#define PI_GPIO_O_RTC_CLK ((1 << 2) << 4) +#define PI_GPIO_I_RTC_DAT ((0 << 3) << 4) +#define PI_GPIO_O_RTC_DAT ((1 << 3) << 4) + +/* Output controls */ +/* Power */ +#define PI_GPIO_PWR_OFF (0 << 0) +#define PI_GPIO_PWR_ON (1 << 0) +/* LED */ +#define PI_GPIO_LED_ON (0 << 1) +#define PI_GPIO_LED_OFF (1 << 1) +/* RTC */ +#define PI_GPIO_RTC_CLK_LO (0 << 2) +#define PI_GPIO_RTC_CLK_HI (1 << 2) +#define PI_GPIO_RTC_DAT_LO (0 << 3) +#define PI_GPIO_RTC_DAT_HI (1 << 3) + +/* Input getters */ +#define PI_GPIO_GET_PWR(reg) (((reg) >> 0) & 1) +#define PI_GPIO_GET_LED(reg) (((reg) >> 1) & 1) +#define PI_GPIO_GET_RTC_CLK(reg) (((reg) >> 2) & 1) +#define PI_GPIO_GET_RTC_DAT(reg) (((reg) >> 3) & 1) diff --git a/src/bb/misc/boxid.c b/src/bb/misc/boxid.c index 4bc1ce32..3b4b493f 100644 --- a/src/bb/misc/boxid.c +++ b/src/bb/misc/boxid.c @@ -2,5 +2,5 @@ #include "PR/bcp.h" u32 osBbGetBoxId(void) { - return IO_READ(PI_60_REG) >> 0x10; + return PI_GPIO_GET_BOXID(IO_READ(PI_GPIO_REG)); } diff --git a/src/bb/misc/errorled.c b/src/bb/misc/errorled.c new file mode 100644 index 00000000..8cf3e53e --- /dev/null +++ b/src/bb/misc/errorled.c @@ -0,0 +1,14 @@ +#include "PR/os_internal.h" +#include "PR/bcp.h" + +void osBbSetErrorLed(u32 value) { + u32 mask = IO_READ(PI_GPIO_REG); + mask &= ~PI_GPIO_LED_OFF; + mask &= ~PI_GPIO_O_LED; + IO_WRITE(PI_GPIO_REG, mask | ((value == 0) ? PI_GPIO_LED_OFF : PI_GPIO_LED_ON) | PI_GPIO_O_LED); +} + +u32 osBbGetErrorLed(void) { + u32 v = PI_GPIO_GET_LED(IO_READ(PI_GPIO_REG)); + return v; +} diff --git a/src/bb/misc/power.c b/src/bb/misc/power.c index 4ab77ead..f87d2723 100644 --- a/src/bb/misc/power.c +++ b/src/bb/misc/power.c @@ -2,11 +2,9 @@ #include "PR/bcp.h" void osBbPowerOn(void) { - // Power control = 1, Power mask = 1 - IO_WRITE(PI_60_REG, 0x11); + IO_WRITE(PI_GPIO_REG, PI_GPIO_O_PWR | PI_GPIO_PWR_ON); } void osBbPowerOff(void) { - // Power control = 0, Power mask = 1 - IO_WRITE(PI_60_REG, 0x10); + IO_WRITE(PI_GPIO_REG, PI_GPIO_O_PWR | PI_GPIO_PWR_OFF); } diff --git a/src/bb/misc/rtc.c b/src/bb/misc/rtc.c index 62d309ff..f42766d1 100644 --- a/src/bb/misc/rtc.c +++ b/src/bb/misc/rtc.c @@ -2,95 +2,149 @@ #include "bcp.h" #include "macros.h" +#define RTC_MASK ((PI_GPIO_O_RTC_DAT | PI_GPIO_RTC_DAT_HI) | (PI_GPIO_O_RTC_CLK | PI_GPIO_RTC_CLK_HI)) + +#define RTC_ADDR 0xD0 +#define RTC_WR 0 +#define RTC_RD 1 + void __osBbDelay(u32 usec); static void write_rtc(u32 x) { - IO_WRITE(PI_60_REG, x); + IO_WRITE(PI_GPIO_REG, x); __osBbDelay(2); } static void send_start(u8 write) { u32 i; u32 j; - u32 mask = IO_READ(PI_60_REG) & ~0xCC; + u32 mask = IO_READ(PI_GPIO_REG) & ~RTC_MASK; u8 byte[2]; - byte[0] = (!write) ? 0xD1 : 0xD0; + byte[0] = (!write) ? (RTC_ADDR | RTC_RD) : (RTC_ADDR | RTC_WR); byte[1] = 0; - write_rtc(mask | 0xC4); - write_rtc(mask | 0xC0); + // Send start signal (DAT HIGH -> LOW while CLK HIGH) assuming both CLK and DAT were initially HIGH + // Cyc -1 | 0 | 1 + // CLK ‾‾‾|‾‾‾|___ + // DAT ‾‾‾|___|___ + write_rtc(mask | (PI_GPIO_O_RTC_DAT | PI_GPIO_RTC_DAT_LO) | (PI_GPIO_O_RTC_CLK | PI_GPIO_RTC_CLK_HI)); + write_rtc(mask | (PI_GPIO_O_RTC_DAT | PI_GPIO_RTC_DAT_LO) | (PI_GPIO_O_RTC_CLK | PI_GPIO_RTC_CLK_LO)); for (i = 0; i < write + 1; i++) { + // Send address in byte[0], for writes also send word address in byte[1] for (j = 0; j < 8; j++) { - u32 b = ((byte[i] >> (7 - j)) & 1) ? 8 : 0; - - write_rtc(mask | (0x80 | b) | 0x40); - write_rtc(mask | (0x80 | b) | 0x44); - write_rtc(mask | (0x80 | b) | 0x40); + u32 b = ((byte[i] >> (7 - j)) & 1) ? PI_GPIO_RTC_DAT_HI : PI_GPIO_RTC_DAT_LO; + + // Transmit single bit to the RTC + // Cyc 0 | 1 | 2 + // CLK ___|‾‾‾|___ + // DAT b | b | b + write_rtc(mask | (PI_GPIO_O_RTC_DAT | b) | (PI_GPIO_O_RTC_CLK | PI_GPIO_RTC_CLK_LO)); + write_rtc(mask | (PI_GPIO_O_RTC_DAT | b) | (PI_GPIO_O_RTC_CLK | PI_GPIO_RTC_CLK_HI)); + write_rtc(mask | (PI_GPIO_O_RTC_DAT | b) | (PI_GPIO_O_RTC_CLK | PI_GPIO_RTC_CLK_LO)); } - write_rtc(mask | 0x40); - write_rtc(mask | 0x44); + + // Toggle CLK to receive ACK from the RTC, but don't read it + // Cyc 0 | 1 + // CLK ___|‾‾‾ + // DAT x | x + write_rtc(mask | PI_GPIO_I_RTC_DAT | (PI_GPIO_O_RTC_CLK | PI_GPIO_RTC_CLK_LO)); + write_rtc(mask | PI_GPIO_I_RTC_DAT | (PI_GPIO_O_RTC_CLK | PI_GPIO_RTC_CLK_HI)); } - write_rtc(mask | 0x40); + + // End on CLK LOW + // Cyc 0 + // CLK ___ + // DAT x + write_rtc(mask | PI_GPIO_I_RTC_DAT | (PI_GPIO_O_RTC_CLK | PI_GPIO_RTC_CLK_LO)); } static void send_stop(void) { - u32 mask = IO_READ(PI_60_REG) & ~0xCC; - write_rtc(mask | 0x80 | 0x40); - write_rtc(mask | 0x80 | 0x44); - write_rtc(mask | 0x80 | 0x4C); + u32 mask = IO_READ(PI_GPIO_REG) & ~RTC_MASK; + + // Send stop signal (DAT LOW -> HIGH while CLK HIGH) + // Cyc 0 | 1 | 2 + // CLK ___|‾‾‾|‾‾‾ + // DAT ___|___|‾‾‾ + write_rtc(mask | (PI_GPIO_O_RTC_DAT | PI_GPIO_RTC_DAT_LO) | (PI_GPIO_O_RTC_CLK | PI_GPIO_RTC_CLK_LO)); + write_rtc(mask | (PI_GPIO_O_RTC_DAT | PI_GPIO_RTC_DAT_LO) | (PI_GPIO_O_RTC_CLK | PI_GPIO_RTC_CLK_HI)); + write_rtc(mask | (PI_GPIO_O_RTC_DAT | PI_GPIO_RTC_DAT_HI) | (PI_GPIO_O_RTC_CLK | PI_GPIO_RTC_CLK_HI)); } static void read_bytes(u8* bytes, u8 len) { u32 ack; u32 i; - u32 mask = IO_READ(PI_60_REG) & ~0xCC; + u32 mask = IO_READ(PI_GPIO_REG) & ~RTC_MASK; while (len-- > 0) { u32 x = 0; + // Read 1 byte for (i = 0; i < 8; i++) { - write_rtc(mask | 0x40); - write_rtc(mask | 0x44); + // Toggle CLK to receive the bit from the RTC + // Cyc 0 | 1 + // CLK ___|‾‾‾ + // DAT x | x + write_rtc(mask | PI_GPIO_I_RTC_DAT | (PI_GPIO_O_RTC_CLK | PI_GPIO_RTC_CLK_LO)); + write_rtc(mask | PI_GPIO_I_RTC_DAT | (PI_GPIO_O_RTC_CLK | PI_GPIO_RTC_CLK_HI)); + + // Read the bit sent by the RTC x <<= 1; - x |= (IO_READ(PI_60_REG) >> 3) & 1; + x |= PI_GPIO_GET_RTC_DAT(IO_READ(PI_GPIO_REG)); } *(bytes++) = x; - ack = (len == 0) ? 0x88 : 0x80; + ack = (len == 0) ? (PI_GPIO_O_RTC_DAT | PI_GPIO_RTC_DAT_HI) : (PI_GPIO_O_RTC_DAT | PI_GPIO_RTC_DAT_LO); - write_rtc(mask | 0x40 | 0x80); - write_rtc(mask | 0x44 | ack); + // Send ACK or NACK, DAT HIGH is NACK while DAT LOW is ACK. NACK is sent at th end. + // Cyc 0 | 1 + // CLK ___|‾‾‾ + // DAT ___| a + write_rtc(mask | (PI_GPIO_O_RTC_DAT | PI_GPIO_RTC_DAT_LO) | (PI_GPIO_O_RTC_CLK | PI_GPIO_RTC_CLK_LO)); + write_rtc(mask | (PI_GPIO_O_RTC_CLK | PI_GPIO_RTC_CLK_HI) | ack); } send_stop(); } static void write_bytes(u8* bytes, u8 len) { u32 i; - u32 mask = IO_READ(PI_60_REG) & ~0xCC; + u32 mask = IO_READ(PI_GPIO_REG) & ~RTC_MASK; while (len-- > 0) { u32 x = *(bytes++); for (i = 0; i < 8; i++) { - u32 b = (x & 0x80) ? 8 : 0; - - write_rtc(mask | (0x80 | b) | 0x40); - write_rtc(mask | (0x80 | b) | 0x44); - write_rtc(mask | (0x80 | b) | 0x44); + u32 b = (x & 0x80) ? PI_GPIO_RTC_DAT_HI : PI_GPIO_RTC_DAT_LO; + + // Transmit single bit to the RTC + // Cyc 0 | 1 | 2 + // CLK ___|‾‾‾|‾‾‾ + // DAT b | b | b + write_rtc(mask | (PI_GPIO_O_RTC_DAT | b) | (PI_GPIO_O_RTC_CLK | PI_GPIO_RTC_CLK_LO)); + write_rtc(mask | (PI_GPIO_O_RTC_DAT | b) | (PI_GPIO_O_RTC_CLK | PI_GPIO_RTC_CLK_HI)); + write_rtc(mask | (PI_GPIO_O_RTC_DAT | b) | (PI_GPIO_O_RTC_CLK | PI_GPIO_RTC_CLK_HI)); x <<= 1; } - write_rtc(mask | 0x40); - write_rtc(mask | 0x44); - IO_READ(PI_60_REG); - write_rtc(mask | 0x40); + + // Toggle CLK to receive ACK from the RTC, read but don't check? + // Cyc 0 | 1 | 2 | 3 + // CLK ___|‾‾‾|‾‾‾|___ + // DAT x | x | x | x + write_rtc(mask | PI_GPIO_I_RTC_DAT | (PI_GPIO_O_RTC_CLK | PI_GPIO_RTC_CLK_LO)); + write_rtc(mask | PI_GPIO_I_RTC_DAT | (PI_GPIO_O_RTC_CLK | PI_GPIO_RTC_CLK_HI)); + IO_READ(PI_GPIO_REG); + write_rtc(mask | PI_GPIO_I_RTC_DAT | (PI_GPIO_O_RTC_CLK | PI_GPIO_RTC_CLK_LO)); } send_stop(); } void osBbRtcInit(void) { - write_rtc(IO_READ(PI_60_REG) | 0xCC); + // Set line state to idle (both CLK and DAT HIGH) + // Cyc 0 + // CLK ‾‾‾ + // DAT ‾‾‾ + write_rtc(IO_READ(PI_GPIO_REG) | (PI_GPIO_O_RTC_DAT | PI_GPIO_RTC_DAT_HI) | (PI_GPIO_O_RTC_CLK | PI_GPIO_RTC_CLK_HI)); } void osBbRtcSet(u8 year, u8 month, u8 day, u8 dow, u8 hour, u8 min, u8 sec) { diff --git a/src/os/initialize.c b/src/os/initialize.c index 7d8821ef..37e28e91 100644 --- a/src/os/initialize.c +++ b/src/os/initialize.c @@ -106,7 +106,7 @@ void INITIALIZE_FUNC() { } if (__osBbIsBb) { - if (IO_READ(PI_60_REG) & 0xC0000000) { + if (IO_READ(PI_GPIO_REG) & PI_GPIO_BOXID_MASK_30_31) { __osBbIsBb = 2; } }