Root/atusb/fw/board_rzusb.c

1/*
2 * fw/board_rzusb.c - RZUSB Board-specific functions (for boot loader and application)
3 *
4 * Written 2016 by Stefan Schmidt
5 * Copyright 2016 Stefan Schmidt
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13
14#include <stdbool.h>
15#include <stdint.h>
16
17#include <avr/io.h>
18#include <avr/interrupt.h>
19#include <avr/boot.h>
20
21#define F_CPU 8000000UL
22#include <util/delay.h>
23
24#include "usb.h"
25#include "at86rf230.h"
26#include "board.h"
27#include "spi.h"
28#include "usb/usb.h"
29
30static bool spi_initialized = 0;
31
32void reset_rf(void)
33{
34    /* set up all the outputs; default port value is 0 */
35
36    DDRB = 0;
37    DDRC = 0;
38    DDRD = 0;
39    PORTB = 0;
40    PORTC = 0;
41    PORTD = 0;
42
43    OUT(LED);
44    OUT(nRST_RF); /* this also resets the transceiver */
45    OUT(SLP_TR);
46
47    spi_init();
48
49    /* AT86RF231 data sheet, 12.4.13, reset pulse width: 625 ns (min) */
50
51    CLR(nRST_RF);
52    _delay_us(2);
53    SET(nRST_RF);
54
55    /* 12.4.14: SPI access latency after reset: 625 ns (min) */
56
57    _delay_us(2);
58
59    /* we must restore TRX_CTRL_0 after each reset (9.6.4) */
60
61    set_clkm();
62}
63
64void led(bool on)
65{
66    if (on)
67        SET(LED);
68    else
69        CLR(LED);
70}
71
72void set_clkm(void)
73{
74    /* switch CLKM to 8 MHz */
75
76    /*
77     * @@@ Note: Atmel advise against changing the external clock in
78     * mid-flight. We should therefore switch to the RC clock first, then
79     * crank up the external clock, and finally switch back to the external
80     * clock. The clock switching procedure is described in the ATmega32U2
81     * data sheet in secton 8.2.2.
82     */
83    spi_begin();
84    spi_send(AT86RF230_REG_WRITE | REG_TRX_CTRL_0);
85    spi_send(0x10);
86    spi_end();
87
88    /* TX_AUTO_CRC_ON, default disabled */
89    spi_begin();
90    spi_send(AT86RF230_REG_WRITE | 0x05);
91    spi_send(0x80);
92    spi_end();
93}
94
95void board_init(void)
96{
97    /* Disable the watchdog timer */
98
99    MCUSR = 0; /* Remove override */
100    WDTCSR |= 1 << WDCE; /* Enable change */
101    WDTCSR = 1 << WDCE; /* Disable watchdog while still enabling
102                   change */
103
104    CLKPR = 1 << CLKPCE;
105    /* We start with a 16 MHz/8 clock. Put the prescaler to 2. */
106    CLKPR = 1 << CLKPS0;
107
108    get_sernum();
109}
110
111void spi_begin(void)
112{
113    if (!spi_initialized)
114        spi_init();
115    CLR(nSS);
116}
117
118void spi_off(void)
119{
120    spi_initialized = 0;
121    SPCR &= ~(1 << SPE);
122}
123
124void spi_init(void)
125{
126    SET(nSS);
127    OUT(SCLK);
128    OUT(MOSI);
129    OUT(nSS);
130    IN(MISO);
131
132    SPCR = (1 << SPE) | (1 << MSTR);
133    SPSR = (1 << SPI2X);
134
135    spi_initialized = 1;
136}
137
138void usb_init(void)
139{
140    USBCON |= 1 << FRZCLK; /* freeze the clock */
141
142    /* enable the PLL and wait for it to lock */
143    /* TODO sheet page 50 For Atmel AT90USB128x only. Do not use with Atmel AT90USB64x. */
144    /* FOR 8 XTAL Mhz only!!! */
145    PLLCSR = ((1 << PLLP1) | (1 << PLLP0));
146    PLLCSR |= 1 << PLLE;
147    while (!(PLLCSR & (1 << PLOCK)));
148
149    UHWCON |= (1 << UVREGE);
150
151    USBCON &= ~((1 << USBE) | (1 << OTGPADE)); /* reset the controller */
152    USBCON |= ((1 << USBE) | (1 << OTGPADE));
153
154    USBCON &= ~(1 << FRZCLK); /* thaw the clock */
155
156    UDCON &= ~(1 << DETACH); /* attach the pull-up */
157    UDIEN = 1 << EORSTE; /* enable device interrupts */
158// UDCON |= 1 << RSTCPU; /* reset CPU on bus reset */
159
160    ep_init();
161}
162
163void board_app_init(void)
164{
165    /* enable timer input capture 1, trigger on rising edge */
166    TCCR1B = (1 << ICES1);
167    TIFR1 = (1 << ICF1);
168    TIMSK1 = (1 << ICIE1);
169}
170

Archive Download this file



interactive