diff --git a/gcn64_protocol.c b/gcn64_protocol.c index 20cf699..14cec03 100644 --- a/gcn64_protocol.c +++ b/gcn64_protocol.c @@ -14,16 +14,18 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ +#include #include #include #include +#include #include "gcn64_protocol.h" #include "gcn64txrx.h" #undef FORCE_KEYBOARD -#define GCN64_BUF_SIZE 320 // Supports up to 39 bytes +#define GCN64_BUF_SIZE 40 static unsigned char gcn64_workbuf[GCN64_BUF_SIZE]; /******** IO port definitions and options **************/ @@ -49,26 +51,12 @@ static unsigned char gcn64_workbuf[GCN64_BUF_SIZE]; */ unsigned char gcn64_protocol_getByte(int offset) { - unsigned char val, b; - unsigned char volatile *addr = gcn64_workbuf + offset; - - for (b=0x80, val=0; b; b>>=1) - { - if (*addr) - val |= b; - addr++; - } - return val; + return gcn64_workbuf[offset/8]; } void gcn64_protocol_getBytes(int offset, int n_bytes, unsigned char *dstbuf) { - int i; - - for (i=0; i 127 (approx 50uS timeout) + brmi rxdone ; > 127 (approx 50uS timeout) sbic GCN64_DATA_PIN, GCN64_DATA_BIT rjmp waitlow_lp - adiw xl, 1 ; count this bit - ; TODO : Check maximum size - ;breq overflow ; > 255 - -#if 0 - st z+, r19 - st z+, r18 - rjmp waithigh -#else ; Compare the low period and the high period. - sub r19, r18 - brcs got1 -got0: - st z+, __zero_reg__ + sub r19, r18 ; Carry is set when 1 + rol r20 + brcs store_byte rjmp waithigh -got1: + +store_byte: + inc r24 ; Count byte + breq overflow ; TODO : Check against r22 st z+,r20 -#endif + ldi r20, 1 waithigh: ldi r19, TIMING_OFFSET waithigh_lp: inc r19 - brmi timeout ; > 127 + brmi frame_error ; This means the line is stuck in a low state... sbis GCN64_DATA_PIN, GCN64_DATA_BIT rjmp waithigh_lp rjmp waitlow -timeout_waitlow: - adiw xl, 1 ; - ; TODO : Check maximum size - ;breq overflow ; > 255 - - ; Compare the low period and the high period. - sub r19, r21 - brcs lastwas1 -lastwas0: - st z+, __zero_reg__ - rjmp rxdone -lastwas1: - st z+,r20 - rjmp rxdone - -overflow: - clr xl - clr xh timeout: + tst r24 + breq rxdone ; If r24 is still zero, we did not receive anything. Return 0. + ; Otherwise, it is a frame error (i.e. A partial byte was received) +frame_error: +overflow: ; Treat overflow as an error as well + ser r24 rxdone: - ; Return the number if received bits in r24,r25 - mov r24, xl ; yl - mov r25, xh ; yh + ; Return the number if received bits in r24 ret diff --git a/gcn64txrx.h b/gcn64txrx.h index 4d27e46..5bdd53c 100644 --- a/gcn64txrx.h +++ b/gcn64txrx.h @@ -2,6 +2,13 @@ #define _gcn64txrx_h__ void gcn64_sendBytes(unsigned char *data, unsigned char n_bytes); -unsigned int gcn64_receiveBits(unsigned char *dstbuf, unsigned char max_bits); + +/** + * \brief Receive up to \max_bytes bytes + * \param dstbuf Destination buffer + * \param max_bytes The maximum number of bytes + * \return The number of received bytes. 0xFF in case of error + */ +unsigned char gcn64_receiveBytes(unsigned char *dstbuf, unsigned char max_bytes); #endif // _gcn64txrx_h__ diff --git a/hiddata.c b/hiddata.c index 5005c12..df36ce5 100644 --- a/hiddata.c +++ b/hiddata.c @@ -58,7 +58,6 @@ uint8_t hiddata_set_report(const struct usb_request *rq, const uint8_t *dat, uin static void hiddata_processCommandBuffer(void) { - int bits; unsigned char channel; #ifdef DEBUG int i; @@ -79,8 +78,7 @@ static void hiddata_processCommandBuffer(void) // TODO : Range checking // cmdbuf[] : RQ, CHN, LEN, data[] channel = cmdbuf[1]; - bits = gcn64_transaction(cmdbuf+3, cmdbuf[2]); - cmdbuf_len = bits / 8; // The above return a number of bits + cmdbuf_len = gcn64_transaction(cmdbuf+3, cmdbuf[2]); gcn64_protocol_getBytes(0, cmdbuf_len, cmdbuf + 3); cmdbuf[2] = cmdbuf_len; cmdbuf_len += 3; // Answer: RQ, CHN, LEN, data[] diff --git a/n64.c b/n64.c index edf9d35..4a04cee 100644 --- a/n64.c +++ b/n64.c @@ -59,9 +59,8 @@ static char initRumble(void) tmpdata[2] = 0x01; memset(tmpdata+3, 0x80, 32); - /* Note: The old test (count > 0) was not reliable. */ count = gcn64_transaction(tmpdata, 35); - if (count == 8) + if (count == 1) return 0; return -1; @@ -76,7 +75,7 @@ static char controlRumble(char enable) tmpdata[2] = 0x1b; memset(tmpdata+3, enable ? 0x01 : 0x00, 32); count = gcn64_transaction(tmpdata, 35); - if (count == 8) + if (count == 1) return 0; return -1;