mirror of
https://github.com/raphnet/dreamcast_usb
synced 2024-12-21 22:58:52 -05:00
Lastest work
This commit is contained in:
parent
29e0e24a94
commit
65dccca103
Binary file not shown.
6
Makefile
6
Makefile
@ -26,6 +26,12 @@ all: $(HEXFILE)
|
|||||||
# characters are not always preserved on Windows. To ensure WinAVR
|
# characters are not always preserved on Windows. To ensure WinAVR
|
||||||
# compatibility define the file type manually.
|
# compatibility define the file type manually.
|
||||||
|
|
||||||
|
rxcode.asm: generate_rxcode.sh
|
||||||
|
generate_rxcode.sh > rxcode.asm
|
||||||
|
|
||||||
|
maplebus.o: maplebus.c rxcode.asm
|
||||||
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
.c.s:
|
.c.s:
|
||||||
$(CC) $(CFLAGS) -S $< -o $@
|
$(CC) $(CFLAGS) -S $< -o $@
|
||||||
|
|
||||||
|
99
dc_pad.c
99
dc_pad.c
@ -89,8 +89,6 @@ const unsigned char dcPadDevDesc[] PROGMEM = { /* USB device descriptor */
|
|||||||
1, /* number of configurations */
|
1, /* number of configurations */
|
||||||
};
|
};
|
||||||
|
|
||||||
static uint32_t request_device_info[1] = { 0x01200000 };
|
|
||||||
static uint32_t get_condition[2] = { 0x09200001, 0x00000001 };
|
|
||||||
|
|
||||||
static void dcInit(void)
|
static void dcInit(void)
|
||||||
{
|
{
|
||||||
@ -102,39 +100,98 @@ static void dcInit(void)
|
|||||||
dcGamepad.deviceDescriptor = (void*)dcPadDevDesc;
|
dcGamepad.deviceDescriptor = (void*)dcPadDevDesc;
|
||||||
dcGamepad.deviceDescriptorSize = sizeof(dcPadDevDesc);
|
dcGamepad.deviceDescriptorSize = sizeof(dcPadDevDesc);
|
||||||
|
|
||||||
maple_sendFrame(request_device_info, 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define MAX_ERRORS 10
|
||||||
|
|
||||||
|
#define STATE_GET_INFO 0
|
||||||
|
#define STATE_WRITE_LCD 1
|
||||||
|
#define STATE_READ_PAD 2
|
||||||
|
|
||||||
|
#define MAPLE_CMD_RQ_DEV_INFO 1
|
||||||
|
#define MAPLE_CMD_RESET_DEVICE 3
|
||||||
|
#define MAPLE_CMD_GET_CONDITION 9
|
||||||
|
#define MAPLE_CMD_BLOCK_WRITE 12
|
||||||
|
|
||||||
|
#define MAPLE_ADDR_PORT(id) ((id)<<6)
|
||||||
|
#define MAPLE_ADDR_PORTA MAPLE_ADDR_PORT(0)
|
||||||
|
#define MAPLE_ADDR_PORTB MAPLE_ADDR_PORT(1)
|
||||||
|
#define MAPLE_ADDR_PORTC MAPLE_ADDR_PORT(2)
|
||||||
|
#define MAPLE_ADDR_PORTD MAPLE_ADDR_PORT(3)
|
||||||
|
#define MAPLE_ADDR_MAIN 0x20
|
||||||
|
#define MAPLE_ADDR_SUB(id) ((1)<<id) /* where id is 0 to 4 */
|
||||||
|
|
||||||
|
#define MAPLE_DC_ADDR 0
|
||||||
|
#define MAPLE_HEADER(cmd,dst_addr,src_addr,len) ( (((cmd)&0xfful)<<24) | (((dst_addr)&0xfful)<<16) | (((src_addr)&0xfful)<<8) | ((len)&0xff))
|
||||||
|
|
||||||
|
static uint32_t request_device_info[1] = { MAPLE_HEADER(MAPLE_CMD_RQ_DEV_INFO, MAPLE_ADDR_MAIN | MAPLE_ADDR_PORTA, MAPLE_DC_ADDR, 0) };
|
||||||
|
static uint32_t get_condition[2] = { 0x09200001, 0x00000001 };
|
||||||
|
static uint32_t block_write_lcd[4] = { 0x0c300003, 0x004, 0, 0xf0f0f0f0 };
|
||||||
|
|
||||||
static void dcReadPad(void)
|
static void dcReadPad(void)
|
||||||
{
|
{
|
||||||
|
static unsigned char state = STATE_GET_INFO;
|
||||||
|
static unsigned char err_count = 0;
|
||||||
|
static unsigned char controller_address = 0;
|
||||||
unsigned char tmp[30];
|
unsigned char tmp[30];
|
||||||
static unsigned char a;
|
|
||||||
int v;
|
int v;
|
||||||
unsigned char lrc = 0;
|
|
||||||
|
switch (state)
|
||||||
|
{
|
||||||
|
case STATE_GET_INFO:
|
||||||
|
maple_sendFrame(request_device_info, 1);
|
||||||
|
v = maple_receivePacket(tmp, 30);
|
||||||
|
_delay_ms(2);
|
||||||
|
if (v==-2) {
|
||||||
|
controller_address = tmp[1]; // sender address
|
||||||
|
state = STATE_WRITE_LCD;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case STATE_WRITE_LCD:
|
||||||
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
again:
|
for (i=0; i<5; i++)
|
||||||
|
{
|
||||||
|
uint32_t request_device_info1[1] = { MAPLE_HEADER(MAPLE_CMD_RQ_DEV_INFO, MAPLE_ADDR_PORTA | MAPLE_ADDR_SUB(i), MAPLE_DC_ADDR, 0) };
|
||||||
|
|
||||||
|
if (controller_address & (1<<i)) {
|
||||||
|
maple_sendFrame(request_device_info1, 1);
|
||||||
|
_delay_us(300);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case STATE_READ_PAD:
|
||||||
maple_sendFrame(get_condition, 2);
|
maple_sendFrame(get_condition, 2);
|
||||||
v = maple_receivePacket(tmp, 30);
|
v = maple_receivePacket(tmp, 30);
|
||||||
|
if (v<=0) {
|
||||||
if (v<0)
|
err_count++;
|
||||||
|
if (err_count > MAX_ERRORS)
|
||||||
|
state = STATE_GET_INFO;
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
err_count = 0;
|
||||||
|
|
||||||
// 8 : Left trigger
|
|
||||||
// 9 : Right trigger
|
|
||||||
// 10 : Buttons
|
|
||||||
// 11 : Buttons
|
|
||||||
// 12 : Joy Y 2
|
|
||||||
// 13 : Joy X 2
|
|
||||||
// 14 : Y axis
|
|
||||||
// 15 : X axis
|
|
||||||
//
|
|
||||||
|
|
||||||
last_built_report[0][0] = tmp[15]-1;
|
// 8 : Buttons
|
||||||
last_built_report[0][1] = tmp[14]-1;
|
// 9 : Buttons
|
||||||
last_built_report[0][2] = tmp[10] ^ 0xff;
|
// 10 : R trig
|
||||||
last_built_report[0][3] = tmp[11] ^ 0xff;
|
// 11 : L trig
|
||||||
|
// 12 : Joy X axis
|
||||||
|
// 13 : Joy Y axis
|
||||||
|
// 14 : Joy X2 axis
|
||||||
|
// 15 : Joy Y2 axis
|
||||||
|
last_built_report[0][0] = tmp[12]-1;
|
||||||
|
last_built_report[0][1] = tmp[13]-1;
|
||||||
|
last_built_report[0][2] = tmp[8] ^ 0xff;
|
||||||
|
last_built_report[0][3] = tmp[9] ^ 0xff;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dcUpdate(void)
|
static void dcUpdate(void)
|
||||||
|
@ -7,6 +7,5 @@ echo "// Number of samples: $NSAMPLES"
|
|||||||
|
|
||||||
for i in `seq 0 $NSAMPLES`
|
for i in `seq 0 $NSAMPLES`
|
||||||
do
|
do
|
||||||
echo "\" in r16, %1\n st z+, r16 \n\" // sample $i "
|
echo "\" in r16, %2\n st z+, r16 \n\" // sample $i "
|
||||||
#echo "\" in r16, %1\n sbi 0x5, 4\ncbi 0x5, 4 \n\" // sample $i "
|
|
||||||
done
|
done
|
||||||
|
100
maplebus.c
100
maplebus.c
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
void maple_init(void)
|
void maple_init(void)
|
||||||
{
|
{
|
||||||
|
DDRC &= ~0x03;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MAPLE_BUF_SIZE 640
|
#define MAPLE_BUF_SIZE 640
|
||||||
@ -118,22 +119,6 @@ static int maplebus_decode(unsigned char *data, unsigned int maxlen)
|
|||||||
last = cur;
|
last = cur;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
for (i=0; i<dst_pos; i++) {
|
|
||||||
int j;
|
|
||||||
for (j=0; j<8; j++) {
|
|
||||||
if (data[i] & (0x80 >> j)) {
|
|
||||||
PORTB |= 0x10;
|
|
||||||
} else {
|
|
||||||
PORTB &= ~0x10;
|
|
||||||
}
|
|
||||||
_delay_us(5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
PORTB &= ~0x10;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return dst_pos;
|
return dst_pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,6 +131,7 @@ int maple_receivePacket(unsigned char *data, unsigned int maxlen)
|
|||||||
{
|
{
|
||||||
unsigned char *tmp = maplebuf;
|
unsigned char *tmp = maplebuf;
|
||||||
unsigned char lrc;
|
unsigned char lrc;
|
||||||
|
unsigned char timeout;
|
||||||
int res, i;
|
int res, i;
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -160,33 +146,47 @@ int maple_receivePacket(unsigned char *data, unsigned int maxlen)
|
|||||||
asm volatile(
|
asm volatile(
|
||||||
" push r30 \n" // 2
|
" push r30 \n" // 2
|
||||||
" push r31 \n" // 2
|
" push r31 \n" // 2
|
||||||
|
" clr %1 \n" // 1 (result=0, no timeout)
|
||||||
|
|
||||||
// " sbi 0x5, 4 \n" // PB4
|
" sbi 0x5, 4 \n" // PB4
|
||||||
// " cbi 0x5, 4 \n"
|
" cbi 0x5, 4 \n"
|
||||||
|
|
||||||
// Loop until a change is detected.
|
// Loop until a change is detected.
|
||||||
" in r17, %1 \n"
|
" ldi r18, 255 \n"
|
||||||
|
" in r17, %2 \n"
|
||||||
"wait_start: \n"
|
"wait_start: \n"
|
||||||
" in r16, %1 \n"
|
" dec r18 \n"
|
||||||
|
" breq timeout \n"
|
||||||
|
" in r16, %2 \n"
|
||||||
" cp r16, r17 \n"
|
" cp r16, r17 \n"
|
||||||
" breq wait_start \n"
|
" breq wait_start \n"
|
||||||
|
" rjmp start_rx \n"
|
||||||
|
|
||||||
|
"timeout:\n"
|
||||||
|
" inc %1 \n" // 1 for timeout
|
||||||
|
" sbi 0x5, 4 \n" // PB4
|
||||||
|
" cbi 0x5, 4 \n"
|
||||||
|
" jmp done \n"
|
||||||
|
|
||||||
|
"start_rx: \n"
|
||||||
" sbi 0x5, 4 \n" // PB4
|
" sbi 0x5, 4 \n" // PB4
|
||||||
" cbi 0x5, 4 \n"
|
" cbi 0x5, 4 \n"
|
||||||
|
|
||||||
// We will loose the first bit(s), but
|
// We will loose the first bit(s), but
|
||||||
// it's only the start of frame.
|
// it's only the start of frame.
|
||||||
|
|
||||||
"start_rx: \n"
|
|
||||||
#include "rxcode.asm"
|
#include "rxcode.asm"
|
||||||
|
|
||||||
|
"done:\n"
|
||||||
" sbi 0x5, 4 \n" // PB4
|
" sbi 0x5, 4 \n" // PB4
|
||||||
" cbi 0x5, 4 \n"
|
" cbi 0x5, 4 \n"
|
||||||
" pop r31 \n" // 2
|
" pop r31 \n" // 2
|
||||||
" pop r30 \n" // 2
|
" pop r30 \n" // 2
|
||||||
: "=z"(tmp)
|
: "=z"(tmp), "=r"(timeout)
|
||||||
: "I" (_SFR_IO_ADDR(PINC))
|
: "I" (_SFR_IO_ADDR(PINC))
|
||||||
: "r16","r17") ;
|
: "r16","r17","r18") ;
|
||||||
|
|
||||||
|
if (timeout)
|
||||||
|
return -1;
|
||||||
|
|
||||||
res = maplebus_decode(data, maxlen);
|
res = maplebus_decode(data, maxlen);
|
||||||
if (res<=0)
|
if (res<=0)
|
||||||
@ -203,6 +203,19 @@ int maple_receivePacket(unsigned char *data, unsigned int maxlen)
|
|||||||
if (lrc)
|
if (lrc)
|
||||||
return -2; // LRC error
|
return -2; // LRC error
|
||||||
|
|
||||||
|
/* Reverse each group of 4 bytes */
|
||||||
|
for (i=0; i<(res-1); i+=4) {
|
||||||
|
unsigned char tmp;
|
||||||
|
|
||||||
|
tmp = data[i+3];
|
||||||
|
data[i+3] = data[i];
|
||||||
|
data[i] = tmp;
|
||||||
|
|
||||||
|
tmp = data[i+2];
|
||||||
|
data[i+2] = data[i+1];
|
||||||
|
data[i+1] = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
return res-1; // remove lrc
|
return res-1; // remove lrc
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -247,36 +260,14 @@ void maple_sendPacket(unsigned char *data, unsigned char len)
|
|||||||
"ld r16, z+ \n"
|
"ld r16, z+ \n"
|
||||||
|
|
||||||
// Sync
|
// Sync
|
||||||
SET_1 SET_5
|
SET_1 SET_5 DLY_8 CLR_1 DLY_8
|
||||||
DLY_8
|
|
||||||
CLR_1
|
|
||||||
DLY_8
|
|
||||||
|
|
||||||
CLR_5
|
CLR_5 DLY_8 SET_5 DLY_8 CLR_5
|
||||||
DLY_8
|
DLY_8 SET_5 DLY_8 CLR_5 DLY_8
|
||||||
SET_5
|
SET_5 DLY_8 CLR_5 DLY_8 SET_5
|
||||||
DLY_8
|
DLY_8 SET_1 CLR_5
|
||||||
|
|
||||||
CLR_5
|
|
||||||
DLY_8
|
|
||||||
SET_5
|
|
||||||
DLY_8
|
|
||||||
|
|
||||||
CLR_5
|
|
||||||
DLY_8
|
|
||||||
SET_5
|
|
||||||
DLY_8
|
|
||||||
|
|
||||||
CLR_5
|
|
||||||
DLY_8
|
|
||||||
SET_5
|
|
||||||
DLY_8
|
|
||||||
|
|
||||||
SET_1
|
|
||||||
CLR_5
|
|
||||||
|
|
||||||
// Pin 5 is low, Pin 1 is high. Ready for 1st phase
|
// Pin 5 is low, Pin 1 is high. Ready for 1st phase
|
||||||
|
|
||||||
// Note: Coded for 16Mhz (8 cycles = 500ns)
|
// Note: Coded for 16Mhz (8 cycles = 500ns)
|
||||||
"next_byte:\n"
|
"next_byte:\n"
|
||||||
|
|
||||||
@ -284,7 +275,7 @@ void maple_sendPacket(unsigned char *data, unsigned char len)
|
|||||||
"out %0, r16 \n" // 1 data
|
"out %0, r16 \n" // 1 data
|
||||||
"cbi %0, 0 \n" // 1 falling edge on pin 1
|
"cbi %0, 0 \n" // 1 falling edge on pin 1
|
||||||
"ld r16, z+ \n" // 2 load phase 2 data
|
"ld r16, z+ \n" // 2 load phase 2 data
|
||||||
"dec r19 \n" // 1 Decrement counter for brne below
|
"nop \n" // 1
|
||||||
"nop \n" // 1
|
"nop \n" // 1
|
||||||
"nop \n" // 1
|
"nop \n" // 1
|
||||||
|
|
||||||
@ -292,11 +283,9 @@ void maple_sendPacket(unsigned char *data, unsigned char len)
|
|||||||
"out %0, r16 \n" // 1 data
|
"out %0, r16 \n" // 1 data
|
||||||
"cbi %0, 1 \n" // 1 falling edge on pin 5
|
"cbi %0, 1 \n" // 1 falling edge on pin 5
|
||||||
"ld r16, z+ \n" // 2
|
"ld r16, z+ \n" // 2
|
||||||
"nop \n" // 1
|
"dec r19 \n" // 1 Decrement counter for brne below
|
||||||
"brne next_byte \n" // 2
|
"brne next_byte \n" // 2
|
||||||
|
|
||||||
"done:\n"
|
|
||||||
|
|
||||||
// End of transmission
|
// End of transmission
|
||||||
SET_5 DLY_4 CLR_5 DLY_4
|
SET_5 DLY_4 CLR_5 DLY_4
|
||||||
CLR_1 DLY_8 SET_1 DLY_8 CLR_1 DLY_8 SET_1 DLY_4 SET_5
|
CLR_1 DLY_8 SET_1 DLY_8 CLR_1 DLY_8 SET_1 DLY_4 SET_5
|
||||||
@ -310,6 +299,7 @@ void maple_sendPacket(unsigned char *data, unsigned char len)
|
|||||||
: "r1","r16","r17","r18","r19","r20","r21"
|
: "r1","r16","r17","r18","r19","r20","r21"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// back to input to receive the answer
|
||||||
DDRC &= ~0x03;
|
DDRC &= ~0x03;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
1282
rxcode.asm
1282
rxcode.asm
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user