Skip to content

Commit 16c460e

Browse files
committed
Add untested code to write RTC on EDX7
1 parent 2f837e5 commit 16c460e

File tree

1 file changed

+93
-0
lines changed

1 file changed

+93
-0
lines changed

src/joybus_rtc.c

+93
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
#include "joybus_rtc.h"
1111
#include "libcart/cart.h"
1212
#include "n64sys.h"
13+
#include "dma.h"
14+
#include "utils.h"
1315
#include "rtc_internal.h"
1416
#include "rtc_internal.h"
1517

@@ -424,6 +426,97 @@ int joybus_rtc_get_time( time_t *out )
424426
return RTC_ESUCCESS;
425427
}
426428

429+
static const uint32_t ED64X_REG_I2C_CMD = 0x1F800018;
430+
static const uint32_t ED64X_REG_I2C_DAT = 0x1F80001C;
431+
432+
static int ed64x_i2c_status(void)
433+
{
434+
return io_read(ED64X_REG_I2C_CMD) & 1;
435+
}
436+
437+
static int ed64x_i2c_cmd(uint8_t cmd)
438+
{
439+
io_write(ED64X_REG_I2C_DAT, cmd);
440+
while (io_read(ED64X_REG_I2C_CMD) & 0x80) {}
441+
return ed64x_i2c_status();
442+
}
443+
444+
static uint8_t ed64x_i2c_dat(uint8_t cmd)
445+
{
446+
io_write(ED64X_REG_I2C_DAT, cmd);
447+
while (io_read(ED64X_REG_I2C_CMD) & 0x80) {}
448+
return io_read(ED64X_REG_I2C_DAT);
449+
}
450+
451+
static void ed64x_i2c_start(void)
452+
{
453+
uint8_t val = io_read(ED64X_REG_I2C_CMD);
454+
io_write(ED64X_REG_I2C_CMD, 0x20);
455+
io_write(ED64X_REG_I2C_DAT, 0xFF);
456+
while (io_read(ED64X_REG_I2C_CMD) & 0x80) {}
457+
io_write(ED64X_REG_I2C_CMD, val | 0x11); // set write mode
458+
}
459+
460+
static void ed64x_i2c_end(void)
461+
{
462+
io_write(ED64X_REG_I2C_CMD, 0x30);
463+
io_write(ED64X_REG_I2C_DAT, 0xFF);
464+
while (io_read(ED64X_REG_I2C_CMD) & 0x80) {}
465+
}
466+
467+
static void ed64x_i2c_setwr(void)
468+
{
469+
io_write(ED64X_REG_I2C_CMD, io_read(ED64X_REG_I2C_CMD) | 0x11);
470+
}
471+
472+
static void ed64x_i2c_setrd(void)
473+
{
474+
io_write(ED64X_REG_I2C_CMD, io_read(ED64X_REG_I2C_CMD) | 0x10);
475+
}
476+
477+
static int ed64x_i2c_write(uint16_t addr, const uint8_t* data, int len)
478+
{
479+
uint8_t bus_addr = addr >> 8;
480+
uint8_t dev_addr = addr & 0xFF;
481+
482+
for (int i=0; i<len; i+=8) {
483+
int retry = 0;
484+
while (1) {
485+
ed64x_i2c_start();
486+
if (ed64x_i2c_cmd(bus_addr) == 0)
487+
break;
488+
ed64x_i2c_end();
489+
if (++retry == 16)
490+
return -1;
491+
}
492+
ed64x_i2c_cmd(dev_addr+i);
493+
for (int j=0; j<MIN(len, 8); j++) {
494+
io_write(ED64X_REG_I2C_DAT, data[i+j]);
495+
while (io_read(ED64X_REG_I2C_CMD) & 0x80) {}
496+
}
497+
ed64x_i2c_end();
498+
}
499+
return 0;
500+
}
501+
502+
static void ed64x_rtc_write( time_t new_time )
503+
{
504+
struct tm * rtc_time = gmtime( &new_time );
505+
uint8_t buf[7];
506+
507+
// The RTC is a DS1337. Encode time according to its datasheet
508+
enum { DS1337_BUS_ADDR = 0xD000 };
509+
510+
buf[0] = bcd_encode( rtc_time->tm_sec );
511+
buf[1] = bcd_encode( rtc_time->tm_min );
512+
buf[2] = bcd_encode( rtc_time->tm_hour ); // bit 6 toggles 12/24 hour mode
513+
buf[3] = bcd_encode( rtc_time->tm_wday + 1 );
514+
buf[4] = bcd_encode( rtc_time->tm_mday );
515+
buf[5] = bcd_encode( rtc_time->tm_mon + 1 ); // bit 7 is the century bit
516+
buf[6] = bcd_encode( rtc_time->tm_year % 100 );
517+
ed64x_i2c_write( DS1337_BUS_ADDR + 0, buf, sizeof(buf) );
518+
}
519+
427520
int joybus_rtc_set_time( time_t new_time )
428521
{
429522
if( new_time < JOYBUS_RTC_TIMESTAMP_MIN || new_time > JOYBUS_RTC_TIMESTAMP_MAX )

0 commit comments

Comments
 (0)