diff --git a/atusb/fw/atusb.c b/atusb/fw/atusb.c index 8e9fed6..deac478 100644 --- a/atusb/fw/atusb.c +++ b/atusb/fw/atusb.c @@ -26,7 +26,6 @@ int main(void) { board_init(); - spi_init(); reset_rf(); user_get_descriptor = sernum_get_descr; diff --git a/atusb/fw/board.c b/atusb/fw/board.c index b4e06b4..292b6a6 100644 --- a/atusb/fw/board.c +++ b/atusb/fw/board.c @@ -53,6 +53,21 @@ static void set_clkm(void) void reset_rf(void) { + /* set up all the outputs; default port value is 0 */ + + DDRB = 0; + DDRC = 0; + DDRD = 0; + PORTB = 0; + PORTC = 0; + PORTD = 0; + + OUT(LED); + OUT(nRST_RF); /* this also resets the transceiver */ + OUT(SLP_TR); + + spi_init(); + /* AT86RF231 data sheet, 12.4.13, reset pulse width: 625 ns (min) */ CLR(nRST_RF); @@ -151,6 +166,40 @@ static void get_sernum(void) } +int gpio(uint8_t port, uint8_t data, uint8_t dir, uint8_t mask, uint8_t *res) +{ + switch (port) { + case 1: + DDRB = (DDRB & ~mask) | dir; + PORTB = (PORTB & ~mask) | data; + _delay_ms(1); + res[0] = PINB; + res[1] = PORTB; + res[2] = DDRB; + break; + case 2: + DDRC = (DDRC & ~mask) | dir; + PORTC = (PORTC & ~mask) | data; + _delay_ms(1); + res[0] = PINC; + res[1] = PORTC; + res[2] = DDRC; + break; + case 3: + DDRD = (DDRD & ~mask) | dir; + PORTD = (PORTD & ~mask) | data; + _delay_ms(1); + res[0] = PIND; + res[1] = PORTD; + res[2] = DDRD; + break; + default: + return 0; + } + return 1; +} + + void board_init(void) { /* Disable the watchdog timer */ @@ -165,12 +214,6 @@ void board_init(void) CLKPR = 1 << CLKPCE; CLKPR = 0; - /* set up all the outputs; default port value is 0 */ - - OUT(LED); - OUT(nRST_RF); /* this also resets the transceiver */ - OUT(SLP_TR); - /* configure timer 1 as a free-running CLK counter */ TCCR1A = 0; diff --git a/atusb/fw/board.h b/atusb/fw/board.h index f37b47f..0e5dbfe 100644 --- a/atusb/fw/board.h +++ b/atusb/fw/board.h @@ -77,6 +77,8 @@ void panic(void); void timer_poll(void); uint64_t timer_read(void); +int gpio(uint8_t port, uint8_t data, uint8_t dir, uint8_t mask, uint8_t *res); + void board_init(void); #endif /* !BOARD_H */ diff --git a/atusb/fw/ep0.c b/atusb/fw/ep0.c index a744b71..2e5d895 100644 --- a/atusb/fw/ep0.c +++ b/atusb/fw/ep0.c @@ -113,6 +113,16 @@ static int my_setup(const struct setup_request *setup) usb_send(&eps[0], buf, size, NULL, NULL); return 1; + case ATUSB_FROM_DEV(ATUSB_GPIO): + debug("ATUSB_GPIO\n"); + if (setup->wLength < 3) + return 0; + if (!gpio(setup->wIndex, setup->wValue, setup->wValue >> 8, + setup->wIndex >> 8, buf)) + return 0; + usb_send(&eps[0], buf, 3, NULL, NULL); + return 1; + case ATUSB_TO_DEV(ATUSB_REG_WRITE): debug("ATUSB_REG_WRITE\n"); spi_begin(); diff --git a/atusb/fw/include/atusb/ep0.h b/atusb/fw/include/atusb/ep0.h index e471454..d887762 100644 --- a/atusb/fw/include/atusb/ep0.h +++ b/atusb/fw/include/atusb/ep0.h @@ -25,6 +25,7 @@ * ->host ATUSB_POLL_INT - - 1 * host-> ATUSB_TEST - - 0 * ->host ATUSB_TIMER - - #bytes (6) + * ->host ATUSB_GPIO dir+data mask+p# 3 * * host-> ATUSB_REG_WRITE value addr 0 * ->host ATUSB_REG_READ - addr 1 @@ -72,6 +73,7 @@ enum atspi_requests { ATUSB_POLL_INT, ATUSB_TEST, /* atusb-sil only */ ATUSB_TIMER, + ATUSB_GPIO, ATUSB_REG_WRITE = 0x20, /* transceiver group */ ATUSB_REG_READ, ATUSB_BUF_WRITE,