Lastest work

This commit is contained in:
Raphaël Assénat 2013-10-15 02:25:39 +00:00
parent 29e0e24a94
commit 65dccca103
6 changed files with 777 additions and 725 deletions

Binary file not shown.

View File

@ -26,6 +26,12 @@ all: $(HEXFILE)
# characters are not always preserved on Windows. To ensure WinAVR
# 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:
$(CC) $(CFLAGS) -S $< -o $@

View File

@ -89,8 +89,6 @@ const unsigned char dcPadDevDesc[] PROGMEM = { /* USB device descriptor */
1, /* number of configurations */
};
static uint32_t request_device_info[1] = { 0x01200000 };
static uint32_t get_condition[2] = { 0x09200001, 0x00000001 };
static void dcInit(void)
{
@ -102,39 +100,98 @@ static void dcInit(void)
dcGamepad.deviceDescriptor = (void*)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 unsigned char state = STATE_GET_INFO;
static unsigned char err_count = 0;
static unsigned char controller_address = 0;
unsigned char tmp[30];
static unsigned char a;
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;
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);
v = maple_receivePacket(tmp, 30);
if (v<0)
if (v<=0) {
err_count++;
if (err_count > MAX_ERRORS)
state = STATE_GET_INFO;
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;
last_built_report[0][1] = tmp[14]-1;
last_built_report[0][2] = tmp[10] ^ 0xff;
last_built_report[0][3] = tmp[11] ^ 0xff;
// 8 : Buttons
// 9 : Buttons
// 10 : R trig
// 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)

View File

@ -7,6 +7,5 @@ echo "// Number of samples: $NSAMPLES"
for i in `seq 0 $NSAMPLES`
do
echo "\" in r16, %1\n st z+, r16 \n\" // sample $i "
#echo "\" in r16, %1\n sbi 0x5, 4\ncbi 0x5, 4 \n\" // sample $i "
echo "\" in r16, %2\n st z+, r16 \n\" // sample $i "
done

View File

@ -10,6 +10,7 @@
void maple_init(void)
{
DDRC &= ~0x03;
}
#define MAPLE_BUF_SIZE 640
@ -118,22 +119,6 @@ static int maplebus_decode(unsigned char *data, unsigned int maxlen)
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;
}
@ -146,6 +131,7 @@ int maple_receivePacket(unsigned char *data, unsigned int maxlen)
{
unsigned char *tmp = maplebuf;
unsigned char lrc;
unsigned char timeout;
int res, i;
//
@ -160,33 +146,47 @@ int maple_receivePacket(unsigned char *data, unsigned int maxlen)
asm volatile(
" push r30 \n" // 2
" push r31 \n" // 2
" clr %1 \n" // 1 (result=0, no timeout)
// " sbi 0x5, 4 \n" // PB4
// " cbi 0x5, 4 \n"
" sbi 0x5, 4 \n" // PB4
" cbi 0x5, 4 \n"
// Loop until a change is detected.
" in r17, %1 \n"
" ldi r18, 255 \n"
" in r17, %2 \n"
"wait_start: \n"
" in r16, %1 \n"
" dec r18 \n"
" breq timeout \n"
" in r16, %2 \n"
" cp r16, r17 \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
" cbi 0x5, 4 \n"
// We will loose the first bit(s), but
// it's only the start of frame.
"start_rx: \n"
#include "rxcode.asm"
"done:\n"
" sbi 0x5, 4 \n" // PB4
" cbi 0x5, 4 \n"
" pop r31 \n" // 2
" pop r30 \n" // 2
: "=z"(tmp)
: "=z"(tmp), "=r"(timeout)
: "I" (_SFR_IO_ADDR(PINC))
: "r16","r17") ;
: "r16","r17","r18") ;
if (timeout)
return -1;
res = maplebus_decode(data, maxlen);
if (res<=0)
@ -203,6 +203,19 @@ int maple_receivePacket(unsigned char *data, unsigned int maxlen)
if (lrc)
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
}
@ -247,36 +260,14 @@ void maple_sendPacket(unsigned char *data, unsigned char len)
"ld r16, z+ \n"
// Sync
SET_1 SET_5
DLY_8
CLR_1
DLY_8
SET_1 SET_5 DLY_8 CLR_1 DLY_8
CLR_5
DLY_8
SET_5
DLY_8
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
CLR_5 DLY_8 SET_5 DLY_8 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
// Note: Coded for 16Mhz (8 cycles = 500ns)
"next_byte:\n"
@ -284,7 +275,7 @@ void maple_sendPacket(unsigned char *data, unsigned char len)
"out %0, r16 \n" // 1 data
"cbi %0, 0 \n" // 1 falling edge on pin 1
"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
@ -292,11 +283,9 @@ void maple_sendPacket(unsigned char *data, unsigned char len)
"out %0, r16 \n" // 1 data
"cbi %0, 1 \n" // 1 falling edge on pin 5
"ld r16, z+ \n" // 2
"nop \n" // 1
"dec r19 \n" // 1 Decrement counter for brne below
"brne next_byte \n" // 2
"done:\n"
// End of transmission
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
@ -310,6 +299,7 @@ void maple_sendPacket(unsigned char *data, unsigned char len)
: "r1","r16","r17","r18","r19","r20","r21"
);
// back to input to receive the answer
DDRC &= ~0x03;
}

1282
rxcode.asm

File diff suppressed because it is too large Load Diff