1
0
mirror of git://projects.qi-hardware.com/ben-wpan.git synced 2024-12-29 19:28:38 +02:00

atusb/fw: new request ATUSB_GPIO for direct GPIO access

reset_rf now resets all GPIOs to their default state. This way, we
can easily recover from an incomplete or incorrect use of ATUSB_GPIO.

- atusb.c (main), board.c (reset_rf): moved call to spi_init into
  reset_rf
- board.c (reset_rf, board_init): moved GPIO setup to reset_rf
- board.c (reset_rf): set GPIOs to reset defaults
- board.h (gpio), board.c: read/modify/write all settings of GPIO
  ports
- include/atusb/ep0.h (enum atspi_requests): added new request
  ATUSB_GPIO
- ep0.c (my_setup): ATUSB_GPIO reads/reconfigures a GPIO port
This commit is contained in:
Werner Almesberger 2011-06-04 09:40:34 -03:00
parent 59469a458d
commit 370cd320ef
5 changed files with 63 additions and 7 deletions

View File

@ -26,7 +26,6 @@
int main(void)
{
board_init();
spi_init();
reset_rf();
user_get_descriptor = sernum_get_descr;

View File

@ -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;

View File

@ -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 */

View File

@ -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();

View File

@ -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,