diff --git a/source/sio.c b/source/sio.c index d837408..170346b 100644 --- a/source/sio.c +++ b/source/sio.c @@ -6,33 +6,28 @@ void sio_normal_inner_slave(void); u8 sio_normal_inner_master(void); +void sio_write(u32); #ifdef HAS_SIO IWRAM_CODE int timed_sio_normal_master(int data, int is_32, int vCountWait) { u8 curr_vcount, target_vcount; - - if(is_32) - REG_SIODATA32 = data; - else - REG_SIODATA8 = (data & 0xFF); - + + sio_write(data); + // - Wait at least 36 us between sends (this is a bit more, but it works) curr_vcount = REG_VCOUNT; target_vcount = curr_vcount + vCountWait; if(target_vcount >= SCANLINES) target_vcount -= SCANLINES; while (target_vcount != REG_VCOUNT); - + // - Set Start flag. REG_SIOCNT |= SIO_START; // - Wait for IRQ (or for Start bit to become zero). while (REG_SIOCNT & SIO_START); // - Process received data. - if(is_32) - return REG_SIODATA32; - else - return (REG_SIODATA8 & 0xFF); + return sio_read(is_32); } IWRAM_CODE void sio_normal_inner_slave() { @@ -54,8 +49,7 @@ IWRAM_CODE void sio_normal_inner_slave() { IWRAM_CODE MAX_OPTIMIZE void sio_handle_irq_slave(int next_data) { REG_SIOCNT |= SIO_SO_HIGH; - REG_SIODATA32 = next_data; - REG_SIODATA8 = next_data; + sio_write(next_data); REG_SIOCNT &= ~(SIO_START | SIO_SO_HIGH); // - Set Start=1 and SO=1 (SO=HIGH indicates not ready, applied after transfer). @@ -67,12 +61,17 @@ IWRAM_CODE MAX_OPTIMIZE void sio_handle_irq_slave(int next_data) { } IWRAM_CODE MAX_OPTIMIZE int sio_read(u8 is_32) { - u32 data = REG_SIODATA8; + u32 data = (REG_SIODATA8 & 0xFF); if(is_32) data = REG_SIODATA32; return data; } +IWRAM_CODE MAX_OPTIMIZE void sio_write(u32 data) { + REG_SIODATA32 = data; + REG_SIODATA8 = (data & 0xFF); +} + IWRAM_CODE void sio_stop_irq_slave() { REG_SIOCNT &= ~SIO_SO_HIGH; REG_SIOCNT &= ~SIO_IRQ; @@ -80,9 +79,8 @@ IWRAM_CODE void sio_stop_irq_slave() { IWRAM_CODE void sio_normal_prepare_irq_slave(int data) { // - Initialize data which is to be sent to master. - REG_SIODATA32 = data; - REG_SIODATA8 = (data & 0xFF); - + sio_write(data); + REG_SIOCNT |= SIO_IRQ; // - Set Start=0 and SO=0 (SO=LOW indicates that slave is (almost) ready). @@ -97,8 +95,8 @@ IWRAM_CODE void sio_normal_prepare_irq_slave(int data) { IWRAM_CODE MAX_OPTIMIZE u32 sio_send_if_ready_master(u32 data, u8 is_32, u8* success) { // - Wait for SI to become LOW (slave ready). (Check timeout here!) - REG_SIODATA32 = data; - REG_SIODATA8 = (data & 0xFF); + sio_write(data); + if (!(REG_SIOCNT & SIO_RDY)) { // - Set Start flag. REG_SIOCNT |= SIO_START; @@ -113,8 +111,8 @@ IWRAM_CODE MAX_OPTIMIZE u32 sio_send_if_ready_master(u32 data, u8 is_32, u8* suc IWRAM_CODE MAX_OPTIMIZE u32 sio_send_master(u32 data, u8 is_32) { // - Wait for SI to become LOW (slave ready). (Check timeout here!) - REG_SIODATA32 = data; - REG_SIODATA8 = (data & 0xFF); + sio_write(data); + // - Set Start flag. REG_SIOCNT |= SIO_START; // - Wait for IRQ (or for Start bit to become zero). @@ -159,20 +157,14 @@ IWRAM_CODE void init_sio_normal(int is_master, int is_32) { IWRAM_CODE int sio_normal(int data, int is_master, int is_32, u8* success) { // - Initialize data which is to be sent to master. - if(is_32) - REG_SIODATA32 = data; - else - REG_SIODATA8 = (data & 0xFF); - + sio_write(data); + if(is_master) *success = sio_normal_inner_master(); else sio_normal_inner_slave(); - + // - Process received data. - if(is_32) - return REG_SIODATA32; - else - return (REG_SIODATA8 & 0xFF); + return sio_read(is_32); } #endif