Skip to content

Commit

Permalink
[iQue] Decompile errorled.c, GPIO register defines (#74)
Browse files Browse the repository at this point in the history
* Decompile errorled.c, GPIO register defines

* LED_OFF <-> LED_ON

* RTC doc

* Correct GPIO
  • Loading branch information
Thar0 authored Nov 28, 2024
1 parent ee9fd71 commit a06d8de
Show file tree
Hide file tree
Showing 6 changed files with 159 additions and 45 deletions.
56 changes: 52 additions & 4 deletions include/PR/bcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)



Expand Down
2 changes: 1 addition & 1 deletion src/bb/misc/boxid.c
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
14 changes: 14 additions & 0 deletions src/bb/misc/errorled.c
Original file line number Diff line number Diff line change
@@ -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;
}
6 changes: 2 additions & 4 deletions src/bb/misc/power.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
124 changes: 89 additions & 35 deletions src/bb/misc/rtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
2 changes: 1 addition & 1 deletion src/os/initialize.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Expand Down

0 comments on commit a06d8de

Please sign in to comment.