mirror of
https://github.com/raphnet/gc_n64_usb-v3
synced 2024-12-21 23:08:53 -05:00
Move inline assembler to assembler file (.S)
This commit is contained in:
parent
d36b9ee4ee
commit
501a4a619c
@ -1,2 +1,2 @@
|
||||
OBJS=main.o usb.o usbpad.o mappings.o gcn64_protocol.o n64.o gamecube.o usart1.o bootloader.o eeprom.o config.o hiddata.o usbstrings.o intervaltimer.o version.o
|
||||
OBJS=main.o usb.o usbpad.o mappings.o gcn64_protocol.o n64.o gamecube.o usart1.o bootloader.o eeprom.o config.o hiddata.o usbstrings.o intervaltimer.o version.o gcn64txrx.o
|
||||
VERSIONSTR=\"3.0.0\"
|
||||
|
344
gcn64_protocol.c
344
gcn64_protocol.c
@ -19,11 +19,12 @@
|
||||
#include <util/delay.h>
|
||||
|
||||
#include "gcn64_protocol.h"
|
||||
#include "gcn64txrx.h"
|
||||
|
||||
#undef FORCE_KEYBOARD
|
||||
|
||||
#define GCN64_BUF_SIZE 600
|
||||
static volatile unsigned char gcn64_workbuf[GCN64_BUF_SIZE];
|
||||
static unsigned char gcn64_workbuf[GCN64_BUF_SIZE];
|
||||
|
||||
/******** IO port definitions and options **************/
|
||||
#ifndef STK525
|
||||
@ -32,45 +33,16 @@ static volatile unsigned char gcn64_workbuf[GCN64_BUF_SIZE];
|
||||
#define GCN64_DATA_PIN PIND
|
||||
#define GCN64_DATA_BIT (1<<0)
|
||||
#define GCN64_BIT_NUM_S "0" // for asm
|
||||
#define FREQ_IS_16MHZ
|
||||
#define DISABLE_INTS_DURING_COMM
|
||||
#else
|
||||
#define GCN64_DATA_PORT PORTA
|
||||
#define GCN64_DATA_DDR DDRA
|
||||
#define GCN64_DATA_PIN PINA
|
||||
#define GCN64_DATA_BIT (1<<0)
|
||||
#define GCN64_BIT_NUM_S "0" // for asm
|
||||
#define FREQ_IS_16MHZ
|
||||
#define DISABLE_INTS_DURING_COMM
|
||||
#endif
|
||||
|
||||
/*
|
||||
* \brief Explode bytes to bits
|
||||
* \param bytes The input byte array
|
||||
* \param num_bytes The number of input bytes
|
||||
* \param workbuf_bit_offset The offset to start writing at
|
||||
* \return number of bits (i.e. written output bytes)
|
||||
*
|
||||
* 1 input byte = 8 output bytes, where each output byte is zero or non-zero depending
|
||||
* on the input byte bits, starting with the most significant one.
|
||||
*/
|
||||
static int bitsToWorkbufBytes(unsigned char *bytes, int num_bytes, int workbuf_bit_offset)
|
||||
{
|
||||
int i, bit;
|
||||
unsigned char p;
|
||||
#define DISABLE_INTS_DURING_COMM
|
||||
|
||||
if (num_bytes * 8 > GCN64_BUF_SIZE)
|
||||
return 0;
|
||||
|
||||
for (i=0,bit=0; i<num_bytes; i++) {
|
||||
for (p=0x80; p; p>>=1) {
|
||||
gcn64_workbuf[bit+workbuf_bit_offset] = bytes[i] & p;
|
||||
bit++;
|
||||
}
|
||||
}
|
||||
|
||||
return bit;
|
||||
}
|
||||
|
||||
/* Read a byte from the buffer (where 1 byte is 1 bit).
|
||||
* MSb first.
|
||||
@ -99,311 +71,6 @@ void gcn64_protocol_getBytes(int offset, int n_bytes, unsigned char *dstbuf)
|
||||
}
|
||||
}
|
||||
|
||||
// The bit timeout is a counter to 127. This is the
|
||||
// start value. Counting from 0 takes hundreads of
|
||||
// microseconds. Because of this, the reception function
|
||||
// "hangs in there" much longer than necessary..
|
||||
#ifdef FREQ_IS_16MHZ
|
||||
#define TIMING_OFFSET 75
|
||||
#else
|
||||
#define TIMING_OFFSET 100 // gives about 12uS. Twice the expected maximum bit period.
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
static unsigned int gcn64_receive()
|
||||
{
|
||||
register unsigned int count=0;
|
||||
|
||||
#define SET_DBG " nop\n"
|
||||
#define CLR_DBG " nop\n"
|
||||
//#define SET_DBG " sbi %3, 4 \n"
|
||||
//#define CLR_DBG " cbi %3, 4 \n"
|
||||
|
||||
// The data line has been released.
|
||||
// The receive part below expects it to be still high
|
||||
// and will wait for it to become low before beginning
|
||||
// the counting.
|
||||
asm volatile(
|
||||
" push r30 \n" // save Z
|
||||
" push r31 \n" // save Z
|
||||
" clr r27 \n" // clear X (%0)
|
||||
" clr r26 \n"
|
||||
|
||||
" clr r16 \n"
|
||||
"initial_wait_low:\n"
|
||||
" inc r16 \n"
|
||||
" breq timeout \n" // overflow to 0
|
||||
" sbic %2, "GCN64_BIT_NUM_S" \n"
|
||||
" rjmp initial_wait_low \n"
|
||||
|
||||
// the next transition is to a high bit
|
||||
" rjmp waithigh \n"
|
||||
|
||||
"waitlow:\n"
|
||||
" ldi r16, %4 \n"
|
||||
"waitlow_lp:\n"
|
||||
" inc r16 \n"
|
||||
" brmi timeout \n" // > 127 (approx 50uS timeout)
|
||||
" sbic %2, "GCN64_BIT_NUM_S" \n"
|
||||
" rjmp waitlow_lp \n"
|
||||
|
||||
" adiw %0, 1 \n" // count this timed low level
|
||||
" breq overflow \n" // > 255
|
||||
" st z+,r16 \n"
|
||||
|
||||
"waithigh:\n"
|
||||
" ldi r16, %4 \n"
|
||||
"waithigh_lp:\n"
|
||||
" inc r16 \n"
|
||||
" brmi timeout \n" // > 127
|
||||
" sbis %2, "GCN64_BIT_NUM_S" \n"
|
||||
" rjmp waithigh_lp \n"
|
||||
" adiw %0, 1 \n" // count this timed high level
|
||||
|
||||
" breq overflow \n" // > 255
|
||||
" st z+,r16 \n"
|
||||
|
||||
" rjmp waitlow \n"
|
||||
|
||||
"overflow: \n"
|
||||
"timeout: \n"
|
||||
" pop r31 \n" // restore z
|
||||
" pop r30 \n" // restore z
|
||||
|
||||
: "=&x" (count) // %0
|
||||
: "z" ((unsigned char volatile *)gcn64_workbuf), // %1
|
||||
"I" (_SFR_IO_ADDR(GCN64_DATA_PIN)), // %2
|
||||
"I" (_SFR_IO_ADDR(PORTB)), // %3
|
||||
"M" (TIMING_OFFSET) // %4
|
||||
: "r16","memory"
|
||||
);
|
||||
|
||||
return count;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void gcn64_sendBytes(unsigned char *data, unsigned char n_bytes)
|
||||
{
|
||||
|
||||
// the value of the gpio is pre-configured to low. We simulate
|
||||
// an open drain output by toggling the direction.
|
||||
#define PULL_DATA " sbi %0, "GCN64_BIT_NUM_S"\n"
|
||||
#define RELEASE_DATA " cbi %0, "GCN64_BIT_NUM_S"\n"
|
||||
|
||||
asm volatile(
|
||||
"mov r23, %2 \n"
|
||||
"tst r23 \n"
|
||||
"breq done_send \n"
|
||||
|
||||
"send_next_byte: \n"
|
||||
"; Check if this is the last byte. \n"
|
||||
"tst r23 \n"
|
||||
"breq send_stop \n"
|
||||
"dec r23 \n"
|
||||
"ld r16, z+ \n"
|
||||
"ldi r17, 0x80 ; mask \n"
|
||||
|
||||
"send_next_bit: \n"
|
||||
"mov r19, r16 \n"
|
||||
"and r19, r17 \n"
|
||||
"brne send1 \n"
|
||||
"nop \n"
|
||||
|
||||
"send0: \n"
|
||||
PULL_DATA
|
||||
// "sbi IO_DDRD, DATA_BIT ; Pull bus to 0 \n"
|
||||
|
||||
"ldi r20, 15 \n"
|
||||
"lp_send0_3us: \n"
|
||||
"dec r20 \n"
|
||||
"brne lp_send0_3us \n"
|
||||
"nop \n"
|
||||
|
||||
RELEASE_DATA
|
||||
// "cbi IO_DDRD, DATA_BIT ; Release bus to 1 \n"
|
||||
"lsr r17 \n"
|
||||
"breq send_next_byte \n"
|
||||
"nop \n"
|
||||
"nop \n"
|
||||
"nop \n"
|
||||
"nop \n"
|
||||
"nop \n"
|
||||
"nop \n"
|
||||
"rjmp send_next_bit \n"
|
||||
|
||||
"send1: \n"
|
||||
PULL_DATA
|
||||
// "sbi IO_DDRD, DATA_BIT ; Pull bus to 0 \n"
|
||||
|
||||
"ldi r20, 4 \n"
|
||||
"lp_send1_1us: \n"
|
||||
"dec r20 \n"
|
||||
"brne lp_send1_1us \n"
|
||||
"nop \n"
|
||||
"nop \n"
|
||||
|
||||
RELEASE_DATA
|
||||
// "cbi IO_DDRD, DATA_BIT ; Release bus to 1 \n"
|
||||
|
||||
"ldi r20, 10 \n"
|
||||
"lp_send1_3us: \n"
|
||||
"dec r20 \n"
|
||||
"brne lp_send1_3us \n"
|
||||
"nop \n"
|
||||
"nop \n"
|
||||
|
||||
"lsr r17 \n"
|
||||
"breq send_next_byte \n"
|
||||
"nop \n"
|
||||
"nop \n"
|
||||
"nop \n"
|
||||
"nop \n"
|
||||
"nop \n"
|
||||
"nop \n"
|
||||
"rjmp send_next_bit \n"
|
||||
|
||||
"send_stop: \n"
|
||||
"nop \n"
|
||||
"nop \n"
|
||||
"nop \n"
|
||||
"nop \n"
|
||||
"nop \n"
|
||||
"nop \n"
|
||||
"nop \n"
|
||||
"nop \n"
|
||||
|
||||
" ; STOP BIT \n"
|
||||
PULL_DATA
|
||||
//" sbi IO_DDRD, DATA_BIT ; Pull low for stop bit \n"
|
||||
" ldi r20, 4 \n"
|
||||
"stbdly0: \n"
|
||||
" dec r20 \n"
|
||||
" brne stbdly0 \n"
|
||||
" nop \n"
|
||||
RELEASE_DATA
|
||||
//" cbi IO_DDRD, DATA_BIT ; Release \n"
|
||||
|
||||
"done_send: \n"
|
||||
:
|
||||
: "I" (_SFR_IO_ADDR(GCN64_DATA_DDR)), // %0
|
||||
"z" ((unsigned char volatile *)gcn64_workbuf), // %1 (Z)
|
||||
"r" (n_bytes) // %2
|
||||
: "r19","r16","r17","r20","r23" );
|
||||
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void gcn64_sendBytes(unsigned char *data, unsigned char n_bytes)
|
||||
{
|
||||
unsigned int bits;
|
||||
|
||||
if (n_bytes == 0)
|
||||
return;
|
||||
|
||||
// Explode the data to one byte per bit for very easy transmission in assembly.
|
||||
// This trades memory for ease of implementation.
|
||||
bits = bitsToWorkbufBytes(data, n_bytes, 0);
|
||||
|
||||
// the value of the gpio is pre-configured to low. We simulate
|
||||
// an open drain output by toggling the direction.
|
||||
#define PULL_DATA " sbi %0, "GCN64_BIT_NUM_S"\n"
|
||||
#define RELEASE_DATA " cbi %0, "GCN64_BIT_NUM_S"\n"
|
||||
|
||||
#ifdef FREQ_IS_16MHZ
|
||||
// busy looping delays based on busy loop and nop tuning.
|
||||
// valid for 16Mhz clock. (Tuned to 1us/3us using a scope)
|
||||
#define DLY_SHORT_1ST "ldi r17, 2\n nop\nrcall sb_dly%=\n "
|
||||
#define DLY_LARGE_1ST "ldi r17, 13\n rcall sb_dly%=\n"
|
||||
#define DLY_SHORT_2ND "nop\nnop\nnop\nnop\n"
|
||||
#define DLY_LARGE_2ND "ldi r17, 9\n rcall sb_dly%=\nnop\nnop\n"
|
||||
|
||||
#else
|
||||
// busy looping delays based on busy loop and nop tuning.
|
||||
// valid for 12Mhz clock.
|
||||
#define DLY_SHORT_1ST "ldi r17, 1\n rcall sb_dly%=\n "
|
||||
#define DLY_LARGE_1ST "ldi r17, 9\n rcall sb_dly%=\n"
|
||||
#define DLY_SHORT_2ND "\n"
|
||||
#define DLY_LARGE_2ND "ldi r17, 5\n rcall sb_dly%=\n nop\nnop\n"
|
||||
#endif
|
||||
|
||||
asm volatile(
|
||||
// Save the modified input operands
|
||||
" push r28 \n" // y
|
||||
" push r29 \n"
|
||||
" push r30 \n" // z
|
||||
" push r31 \n"
|
||||
|
||||
"sb_loop%=: \n"
|
||||
" ld r16, z+ \n"
|
||||
" tst r16 \n"
|
||||
" breq sb_send0%= \n"
|
||||
" brne sb_send1%= \n"
|
||||
|
||||
" rjmp sb_end%= \n" // not reached
|
||||
|
||||
|
||||
"sb_send0%=: \n"
|
||||
" nop \n"
|
||||
PULL_DATA
|
||||
DLY_LARGE_1ST
|
||||
RELEASE_DATA
|
||||
DLY_SHORT_2ND
|
||||
" sbiw %1, 1 \n"
|
||||
" brne sb_loop%= \n"
|
||||
" rjmp sb_end%= \n"
|
||||
|
||||
"sb_send1%=: \n"
|
||||
PULL_DATA
|
||||
DLY_SHORT_1ST
|
||||
RELEASE_DATA
|
||||
DLY_LARGE_2ND
|
||||
" sbiw %1, 1 \n"
|
||||
" brne sb_loop%= \n"
|
||||
" rjmp sb_end%= \n"
|
||||
|
||||
// delay sub (arg r17)
|
||||
"sb_dly%=: \n"
|
||||
" dec r17 \n"
|
||||
" brne sb_dly%= \n"
|
||||
" ret \n"
|
||||
|
||||
|
||||
"sb_end%=:\n"
|
||||
// going here is fast so we need to extend the last
|
||||
// delay by 500nS
|
||||
" nop\n "
|
||||
#ifdef FREQ_IS_16MHZ
|
||||
" nop\n"
|
||||
#endif
|
||||
" pop r31 \n"
|
||||
" pop r30 \n"
|
||||
PULL_DATA
|
||||
" pop r29 \n"
|
||||
" pop r28 \n"
|
||||
//DLY_SHORT_1ST
|
||||
"nop\nnop\nnop\nnop\n"
|
||||
RELEASE_DATA
|
||||
|
||||
// Now, we need to loop until the wire is high to
|
||||
// prevent the reception code from thinking this is
|
||||
// the beginning of the first reply bit.
|
||||
|
||||
" ldi r16, 0xff \n" // setup a timeout
|
||||
"sb_waitHigh%=: \n"
|
||||
" dec r16 \n" // decrement timeout
|
||||
" breq sb_wait_high_done%= \n" // handle timeout condition
|
||||
" sbis %3, "GCN64_BIT_NUM_S" \n" // Read the port
|
||||
" rjmp sb_waitHigh%= \n"
|
||||
"sb_wait_high_done%=:\n"
|
||||
:
|
||||
: "I" (_SFR_IO_ADDR(GCN64_DATA_DDR)), // %0
|
||||
"w" (bits), // %1
|
||||
"z" ((unsigned char volatile *)gcn64_workbuf), // %2
|
||||
"I" (_SFR_IO_ADDR(GCN64_DATA_PIN)) // %3
|
||||
: "r16", "r17");
|
||||
}
|
||||
#endif
|
||||
|
||||
/* \brief Decode the received length of low/high states to byte-per-bit format
|
||||
*
|
||||
* The result is in workbuf.
|
||||
@ -484,7 +151,8 @@ int gcn64_transaction(unsigned char *data_out, int data_out_len)
|
||||
cli();
|
||||
#endif
|
||||
gcn64_sendBytes(data_out, data_out_len);
|
||||
count = gcn64_receive();
|
||||
//count = gcn64_receive();
|
||||
count = gcn64_receiveBits(gcn64_workbuf, 0);
|
||||
SREG = sreg;
|
||||
|
||||
if (!count)
|
||||
@ -612,5 +280,3 @@ int gcn64_detectController(void)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
208
gcn64txrx.S
Normal file
208
gcn64txrx.S
Normal file
@ -0,0 +1,208 @@
|
||||
#include <avr/io.h>
|
||||
|
||||
.text
|
||||
.global gcn64_sendBytes
|
||||
.global gcn64_receiveBits
|
||||
|
||||
#define xl r26
|
||||
#define xh r27
|
||||
#define yl r28
|
||||
#define yh r29
|
||||
#define zl r30
|
||||
#define zh r31
|
||||
|
||||
/* the value of the gpio is pre-configured to low. We simulate
|
||||
an open drain output by toggling the direction */
|
||||
|
||||
#ifdef STK525
|
||||
#define GCN64_DATA_PORT _SFR_IO_ADDR(PORTA)
|
||||
#define GCN64_DATA_DDR _SFR_IO_ADDR(DDRA)
|
||||
#define GCN64_DATA_PIN _SFR_IO_ADDR(PINA)
|
||||
#else
|
||||
#define GCN64_DATA_PORT _SFR_IO_ADDR(PORTD)
|
||||
#define GCN64_DATA_DDR _SFR_IO_ADDR(DDRD)
|
||||
#define GCN64_DATA_PIN _SFR_IO_ADDR(PIND)
|
||||
#endif
|
||||
#define GCN64_DATA_BIT 0
|
||||
|
||||
#if F_CPU != 16000000L
|
||||
#error Only 16MHz clock supported
|
||||
#endif
|
||||
|
||||
; The bit timeout is a counter to 127. This is the
|
||||
; start value. Counting from 0 takes hundreads of
|
||||
; microseconds. Because of this, the reception function
|
||||
; "hangs in there" much longer than necessary..
|
||||
#define TIMING_OFFSET 75
|
||||
|
||||
; unsigned int gcn64_receiveBytes(unsigned char *dstbuf, unsigned char max_bytes);
|
||||
; r24,r25 : dstbuf
|
||||
; r22 : max bytes (for fututre use)
|
||||
; return: count in r24,r25
|
||||
gcn64_receiveBits:
|
||||
clr xl
|
||||
clr xh
|
||||
mov zl, r24
|
||||
mov zh, r25
|
||||
|
||||
clr r18
|
||||
initial_wait_low:
|
||||
inc r18
|
||||
breq timeout ; overflow to 0
|
||||
sbic GCN64_DATA_PIN, GCN64_DATA_BIT
|
||||
rjmp initial_wait_low
|
||||
|
||||
; the next transition is to a high bit
|
||||
rjmp waithigh
|
||||
|
||||
waitlow:
|
||||
ldi r18, TIMING_OFFSET
|
||||
waitlow_lp:
|
||||
inc r18
|
||||
brmi timeout ; > 127 (approx 50uS timeout)
|
||||
sbic GCN64_DATA_PIN, GCN64_DATA_BIT
|
||||
rjmp waitlow_lp
|
||||
|
||||
adiw xl, 1 ; count this timed low level
|
||||
breq overflow ; > 255
|
||||
st z+,r18
|
||||
|
||||
waithigh:
|
||||
ldi r18, TIMING_OFFSET
|
||||
waithigh_lp:
|
||||
inc r18
|
||||
brmi timeout ; > 127
|
||||
sbis GCN64_DATA_PIN, GCN64_DATA_BIT
|
||||
rjmp waithigh_lp
|
||||
adiw xl, 1 ; count this timed high level
|
||||
|
||||
breq overflow ; > 255
|
||||
st z+,r18
|
||||
|
||||
rjmp waitlow
|
||||
|
||||
overflow:
|
||||
timeout:
|
||||
; Return the number if received bits in r24,r25
|
||||
mov r24, xl ; yl
|
||||
mov r25, xh ; yh
|
||||
ret
|
||||
|
||||
|
||||
/************************************************
|
||||
* Send data using the N64/GC serial protocol which
|
||||
* is as follows:
|
||||
* 0 1
|
||||
* __ _____
|
||||
* ____| __|
|
||||
* ^ ^ ^ ^ ^ ^
|
||||
* 3us 1us 1us 3us
|
||||
*
|
||||
* To send a 1, the pin direction is set to input.
|
||||
* To send a 0, the pin direction is set to output.
|
||||
* (of course, it's value is preset to zero)
|
||||
*
|
||||
* At 16 mhz, a 1us period is 16 cycles. Thus a 3us period
|
||||
* is 48 cycles.
|
||||
*
|
||||
* Pointer to data is passed in r24, r25
|
||||
* Number of bytes to send is passed in r22
|
||||
*
|
||||
* A stop bit is added at thy end of the packet.
|
||||
*
|
||||
************************************************/
|
||||
gcn64_sendBytes:
|
||||
; Move r23,r24 pointer to z
|
||||
mov zl, r24
|
||||
mov zh, r25
|
||||
|
||||
tst r22
|
||||
breq done_send
|
||||
|
||||
send_next_byte:
|
||||
; Check if this is the last byte.
|
||||
tst r22
|
||||
breq send_stop
|
||||
dec r22
|
||||
ld r21, z+
|
||||
ldi r27, 0x80 ; mask
|
||||
|
||||
send_next_bit:
|
||||
mov r19, r21
|
||||
and r19, r27
|
||||
brne send1
|
||||
nop
|
||||
|
||||
send0:
|
||||
sbi GCN64_DATA_DDR, GCN64_DATA_BIT ; Pull bus to 0
|
||||
|
||||
ldi r20, 15
|
||||
lp_send0_3us:
|
||||
dec r20
|
||||
brne lp_send0_3us
|
||||
nop
|
||||
|
||||
cbi GCN64_DATA_DDR, GCN64_DATA_BIT ; Release bus to 1
|
||||
|
||||
|
||||
lsr r27
|
||||
breq send_next_byte
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
rjmp send_next_bit
|
||||
|
||||
send1:
|
||||
sbi GCN64_DATA_DDR, GCN64_DATA_BIT ; Pull bus to 0
|
||||
|
||||
ldi r20, 4
|
||||
lp_send1_1us:
|
||||
dec r20
|
||||
brne lp_send1_1us
|
||||
nop
|
||||
nop
|
||||
|
||||
cbi GCN64_DATA_DDR, GCN64_DATA_BIT ; Release bus to 1
|
||||
|
||||
ldi r20, 10
|
||||
lp_send1_3us:
|
||||
dec r20
|
||||
brne lp_send1_3us
|
||||
nop
|
||||
nop
|
||||
|
||||
lsr r27
|
||||
breq send_next_byte
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
rjmp send_next_bit
|
||||
|
||||
send_stop:
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
; STOP BIT
|
||||
sbi GCN64_DATA_DDR, GCN64_DATA_BIT ; Pull low for stop bit
|
||||
ldi r20, 4
|
||||
stbdly0:
|
||||
dec r20
|
||||
brne stbdly0
|
||||
nop
|
||||
cbi GCN64_DATA_DDR, GCN64_DATA_BIT ; Release
|
||||
|
||||
done_send:
|
||||
ret
|
||||
|
||||
|
7
gcn64txrx.h
Normal file
7
gcn64txrx.h
Normal file
@ -0,0 +1,7 @@
|
||||
#ifndef _gcn64txrx_h__
|
||||
#define _gcn64txrx_h__
|
||||
|
||||
void gcn64_sendBytes(unsigned char *data, unsigned char n_bytes);
|
||||
unsigned int gcn64_receiveBits(unsigned char *dstbuf, unsigned char max_bits);
|
||||
|
||||
#endif // _gcn64txrx_h__
|
Loading…
Reference in New Issue
Block a user