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;