1
0
mirror of git://projects.qi-hardware.com/ben-wpan.git synced 2024-11-25 10:06:15 +02:00

atusb: fw: add support for rzusbstick

This patch adds support for the rzusbstick for the atusb firmware.
More detailed information about this usb stick:

http://www.atmel.com/tools/rzusbstick.aspx

Original I have the rzraven kit:

http://www.atmel.com/tools/rzraven.aspx

Which comes with a special cable and avr dragon programmer. You need
some programmer and wires to the programmers pins. To lookup how to
connect the programmer to the rzusbstick pinout, see:

http://www.atmel.com/Images/doc8117.pdf

page 22 (schematics of the rzusbstick).

Difference between atusb and rzusbstick(rzusb) is mainly the at86rf231
vs at86rf230 one. The rzusb contains the at86rf230 which is a little bit
hard to deal with it (and has a huge errata inside the datasheet).
Nevertheless with small schanges the atusb firmware can run now on the
rzusb. The rzusb contains also a bigger mcu, so we can maybe cache more
pdus for receive handling.

To compile the rzusb firmware call:
make NAME=rzusb

this will generate the rzusb.bin

then call the programmer (in my case avrdude):
avrdude -P usb -c dragon_jtag -p usb1287 -U flash:w:rzusb.bin

NOTE: currently there is no chance (I suppose) to ensure that the atusb
receive the correct firmware, so don't try to flash the atusb with the
rzusb firmware! Also the vendor and product id is the same.

This currently a RFC, it's a quick hack and I think we should update
more the documentation to support the rzusb.

Signed-off-by: Alexander Aring <alex.aring@gmail.com>
Cc: Stefan Schmidt <stefan@osg.samsung.com>
Cc: Werner Almesberger <werner@almesberger.net>
This commit is contained in:
Alexander Aring 2015-05-24 14:37:38 +02:00 committed by Stefan Schmidt
parent fde38d59e3
commit 5129029d3b
8 changed files with 135 additions and 25 deletions

View File

@ -18,7 +18,13 @@ CFLAGS = -g -mmcu=$(CHIP) -DBOOT_ADDR=$(BOOT_ADDR) \
-Wall -Wextra -Wshadow -Werror -Wno-unused-parameter \ -Wall -Wextra -Wshadow -Werror -Wno-unused-parameter \
-Wmissing-prototypes -Wmissing-declarations -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wstrict-prototypes
ifeq ($(NAME),rzusb)
CHIP=at90usb1287
CFLAGS += -DRZUSB
else
CHIP=atmega32u2 CHIP=atmega32u2
CFLAGS += -DATUSB
endif
HOST=jlime HOST=jlime
BOOT_ADDR=0x7000 BOOT_ADDR=0x7000

View File

@ -37,11 +37,13 @@ int main(void)
usb_init(); usb_init();
ep0_init(); ep0_init();
#ifdef ATUSB
timer_init(); timer_init();
/* move interrupt vectors to 0 */ /* move interrupt vectors to 0 */
MCUCR = 1 << IVCE; MCUCR = 1 << IVCE;
MCUCR = 0; MCUCR = 0;
#endif
sei(); sei();

View File

@ -41,11 +41,24 @@ static void set_clkm(void)
* clock. The clock switching procedure is described in the ATmega32U2 * clock. The clock switching procedure is described in the ATmega32U2
* data sheet in secton 8.2.2. * data sheet in secton 8.2.2.
*/ */
#ifdef ATUSB
spi_begin(); spi_begin();
spi_send(AT86RF230_REG_WRITE | REG_TRX_CTRL_0); spi_send(AT86RF230_REG_WRITE | REG_TRX_CTRL_0);
spi_send(CLKM_CTRL_8MHz); spi_send(CLKM_CTRL_8MHz);
spi_end(); spi_end();
#endif
#ifdef RZUSB
spi_begin();
spi_send(AT86RF230_REG_WRITE | REG_TRX_CTRL_0);
spi_send(0x10);
spi_end();
/* TX_AUTO_CRC_ON, default disabled */
spi_begin();
spi_send(AT86RF230_REG_WRITE | 0x05);
spi_send(0x80);
spi_end();
#endif
} }
@ -131,10 +144,15 @@ void board_init(void)
WDTCSR = 1 << WDCE; /* Disable watchdog while still enabling WDTCSR = 1 << WDCE; /* Disable watchdog while still enabling
change */ change */
/* We start with a 1 MHz/8 clock. Disable the prescaler. */
CLKPR = 1 << CLKPCE; CLKPR = 1 << CLKPCE;
#ifdef ATUSB
/* We start with a 1 MHz/8 clock. Disable the prescaler. */
CLKPR = 0; CLKPR = 0;
#endif
#ifdef RZUSB
/* We start with a 16 MHz/8 clock. Put the prescaler to 2. */
CLKPR = 1 << CLKPS0;
#endif
get_sernum(); get_sernum();
} }

View File

@ -18,7 +18,7 @@
#include <atusb/atusb.h> #include <atusb/atusb.h>
#ifdef ATUSB
#define LED_PORT B #define LED_PORT B
#define LED_BIT 6 #define LED_BIT 6
#define nRST_RF_PORT C #define nRST_RF_PORT C
@ -38,6 +38,34 @@
#define IRQ_RF_PORT D #define IRQ_RF_PORT D
#define IRQ_RF_BIT 0 #define IRQ_RF_BIT 0
#define SPI_WAIT_DONE() while (!(UCSR1A & 1 << RXC1))
#define SPI_DATA UDR1
#endif
#ifdef RZUSB
#define LED_PORT D
#define LED_BIT 7
#define nRST_RF_PORT B
#define nRST_RF_BIT 5
#define SLP_TR_PORT B
#define SLP_TR_BIT 4
#define SCLK_PORT B
#define SCLK_BIT 1
#define MOSI_PORT B
#define MOSI_BIT 2
#define MISO_PORT B
#define MISO_BIT 3
#define nSS_PORT B
#define nSS_BIT 0
#define IRQ_RF_PORT D
#define IRQ_RF_BIT 4
#define SPI_WAIT_DONE() while ((SPSR & (1 << SPIF)) == 0)
#define SPI_DATA SPDR
#endif
#define SET_2(p, b) PORT##p |= 1 << (b) #define SET_2(p, b) PORT##p |= 1 << (b)
#define CLR_2(p, b) PORT##p &= ~(1 << (b)) #define CLR_2(p, b) PORT##p &= ~(1 << (b))

View File

@ -154,8 +154,12 @@ static void done(void *user)
uint8_t irq_serial; uint8_t irq_serial;
#ifdef ATUSB
ISR(INT0_vect) ISR(INT0_vect)
#endif
#ifdef RZUSB
ISR(TIMER1_CAPT_vect)
#endif
{ {
if (mac_irq) { if (mac_irq) {
if (mac_irq()) if (mac_irq())
@ -168,10 +172,20 @@ ISR(INT0_vect)
} }
} }
#ifdef ATUSB
void board_app_init(void) void board_app_init(void)
{ {
/* enable INT0, trigger on rising edge */ /* enable INT0, trigger on rising edge */
EICRA = 1 << ISC01 | 1 << ISC00; EICRA = 1 << ISC01 | 1 << ISC00;
EIMSK = 1 << 0; EIMSK = 1 << 0;
} }
#endif
#ifdef RZUSB
void board_app_init(void)
{
/* enable timer input capture 1, trigger on rising edge */
TCCR1B = (1 << ICES1);
TIFR1 = (1 << ICF1);
TIMSK1 = (1 << ICIE1);
}
#endif

View File

@ -21,7 +21,6 @@
#include "board.h" #include "board.h"
#include "mac.h" #include "mac.h"
#define RX_BUFS 3 #define RX_BUFS 3
@ -102,12 +101,22 @@ static void tx_ack_done(void *user)
usb_next(); usb_next();
} }
static void change_state(uint8_t new)
{
while ((reg_read(REG_TRX_STATUS) & TRX_STATUS_MASK) ==
TRX_STATUS_TRANSITION);
reg_write(REG_TRX_STATE, new);
}
static void rx_done(void *user) static void rx_done(void *user)
{ {
led(0); led(0);
next_buf(&rx_out); next_buf(&rx_out);
usb_next(); usb_next();
#ifdef RZUSB
/* slap at86rf230 - reduce fragmentation issue */
change_state(TRX_STATUS_RX_AACK_ON);
#endif
} }
@ -117,10 +126,16 @@ static void receive_frame(void)
uint8_t *buf; uint8_t *buf;
spi_begin(); spi_begin();
#ifdef ATUSB
if (!(spi_io(AT86RF230_BUF_READ) & RX_CRC_VALID)) { if (!(spi_io(AT86RF230_BUF_READ) & RX_CRC_VALID)) {
spi_end(); spi_end();
return; return;
} }
#endif
#ifdef RZUSB
spi_io(AT86RF230_BUF_READ);
#endif
size = spi_recv(); size = spi_recv();
if (!size || (size & 0x80)) { if (!size || (size & 0x80)) {
spi_end(); spi_end();
@ -169,14 +184,6 @@ static bool handle_irq(void)
/* ----- TX/RX ------------------------------------------------------------- */ /* ----- TX/RX ------------------------------------------------------------- */
static void change_state(uint8_t new)
{
while ((reg_read(REG_TRX_STATUS) & TRX_STATUS_MASK) ==
TRX_STATUS_TRANSITION);
reg_write(REG_TRX_STATE, new);
}
bool mac_rx(int on) bool mac_rx(int on)
{ {
if (on) { if (on) {
@ -209,12 +216,21 @@ static void do_tx(void *user)
} }
while (status != TRX_STATUS_RX_ON && status != TRX_STATUS_RX_AACK_ON); while (status != TRX_STATUS_RX_ON && status != TRX_STATUS_RX_AACK_ON);
#ifdef ATUSB
/* /*
* We use TRX_CMD_FORCE_PLL_ON instead of TRX_CMD_PLL_ON because a new * We use TRX_CMD_FORCE_PLL_ON instead of TRX_CMD_PLL_ON because a new
* reception may have begun while we were still working on the previous * reception may have begun while we were still working on the previous
* one. * one.
*/ */
reg_write(REG_TRX_STATE, TRX_CMD_FORCE_PLL_ON); reg_write(REG_TRX_STATE, TRX_CMD_FORCE_PLL_ON);
#endif
#ifdef RZUSB
/*
* at86rf230 doesn't support force change, nevetherless this works
* somehow
*/
reg_write(REG_TRX_STATE, TRX_CMD_PLL_ON);
#endif
handle_irq(); handle_irq();

View File

@ -34,9 +34,9 @@ void spi_begin(void)
uint8_t spi_io(uint8_t v) uint8_t spi_io(uint8_t v)
{ {
// while (!(UCSR1A & 1 << UDRE1)); // while (!(UCSR1A & 1 << UDRE1));
UDR1 = v; SPI_DATA = v;
while (!(UCSR1A & 1 << RXC1)); SPI_WAIT_DONE();
return UDR1; return SPDR;
} }
@ -51,21 +51,26 @@ void spi_recv_block(uint8_t *buf, uint8_t n)
{ {
if (!n) if (!n)
return; return;
UDR1 = 0; SPI_DATA = 0;
while (--n) { while (--n) {
while (!(UCSR1A & 1 << RXC1)); SPI_WAIT_DONE();
*buf++ = UDR1; *buf++ = SPI_DATA;
UDR1 = 0; SPI_DATA = 0;
} }
while (!(UCSR1A & 1 << RXC1)); SPI_WAIT_DONE();
*buf++ = UDR1; *buf++ = SPI_DATA;
} }
void spi_off(void) void spi_off(void)
{ {
spi_initialized = 0; spi_initialized = 0;
UCSR1B = 0; #ifdef ATUSB
UCSR1B = 0;
#endif
#ifdef RZUSB
SPCR &= ~(1 << SPE);
#endif
} }
@ -77,12 +82,18 @@ void spi_init(void)
OUT(nSS); OUT(nSS);
IN(MISO); IN(MISO);
#ifdef ATUSB
UBRR1 = 0; /* set bit rate to zero to begin */ UBRR1 = 0; /* set bit rate to zero to begin */
UCSR1C = 1 << UMSEL11 | 1 << UMSEL10; UCSR1C = 1 << UMSEL11 | 1 << UMSEL10;
/* set MSPI, MSB first, SPI data mode 0 */ /* set MSPI, MSB first, SPI data mode 0 */
UCSR1B = 1 << RXEN1 | 1 << TXEN1; UCSR1B = 1 << RXEN1 | 1 << TXEN1;
/* enable receiver and transmitter */ /* enable receiver and transmitter */
UBRR1 = 0; /* reconfirm the bit rate */ UBRR1 = 0; /* reconfirm the bit rate */
#endif
#ifdef RZUSB
SPCR = (1 << SPE) | (1 << MSTR);
SPSR = (1 << SPI2X);
#endif
spi_initialized = 1; spi_initialized = 1;
} }

View File

@ -252,12 +252,27 @@ void usb_init(void)
USBCON |= 1 << FRZCLK; /* freeze the clock */ USBCON |= 1 << FRZCLK; /* freeze the clock */
/* enable the PLL and wait for it to lock */ /* enable the PLL and wait for it to lock */
#ifdef ATUSB
PLLCSR &= ~(1 << PLLP2 | 1 << PLLP1 | 1 << PLLP0); PLLCSR &= ~(1 << PLLP2 | 1 << PLLP1 | 1 << PLLP0);
#endif
#ifdef RZUSB
/* TODO sheet page 50 For Atmel AT90USB128x only. Do not use with Atmel AT90USB64x. */
/* FOR 8 XTAL Mhz only!!! */
PLLCSR = ((1 << PLLP1) | (1 << PLLP0));
#endif
PLLCSR |= 1 << PLLE; PLLCSR |= 1 << PLLE;
while (!(PLLCSR & (1 << PLOCK))); while (!(PLLCSR & (1 << PLOCK)));
#ifdef ATUSB
USBCON &= ~(1 << USBE); /* reset the controller */ USBCON &= ~(1 << USBE); /* reset the controller */
USBCON |= 1 << USBE; USBCON |= 1 << USBE;
#endif
#ifdef RZUSB
UHWCON |= (1 << UVREGE);
USBCON &= ~((1 << USBE) | (1 << OTGPADE)); /* reset the controller */
USBCON |= ((1 << USBE) | (1 << OTGPADE));
#endif
USBCON &= ~(1 << FRZCLK); /* thaw the clock */ USBCON &= ~(1 << FRZCLK); /* thaw the clock */