Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[iQue] Decompile errorled.c, GPIO register defines #74

Open
wants to merge 4 commits into
base: ique
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading