e2f5377386696dda559d8df185a9d67aea24295e
[goodfet] / firmware / lib / atmega128rfa1.c
1 #include "platform.h"
2
3 #include <avr/io.h>
4 #include <util/delay.h>
5
6 //! Receive a byte.
7 unsigned char serial0_rx(){
8   while( !(UCSR0A & (1 << RXC0)) );
9   return UDR0;
10 }
11
12
13 //! Transmit a byte.
14 void serial0_tx(unsigned char x){
15   while (!(UCSR0A & (1<<UDRE0)) );
16   UDR0 = x;
17 }
18
19
20 //! Set the baud rate.
21 void setbaud0(unsigned char rate){
22   /* disable everything briefly */
23   UCSR0B = 0;
24
25   int32_t r;
26   switch(rate){
27   case 1://9600 baud
28     r = 9600;
29     break;
30   case 2://19200 baud
31     r = 19200;
32     break;
33   case 3://38400 baud
34     r = 38400;
35     break;
36   case 4://57600 baud
37     r = 57600;
38     break;
39
40   default:
41   case 5://115200 baud
42     r = 115200;
43     break;
44   }
45
46   /* enabling rx/tx must be done before frame/baud setup */
47   UCSR0B = ((1 << TXEN0) | (1 << RXEN0));
48
49   UCSR0A = (1 << U2X0);   /* double the baud rate */
50   UCSR0C = (3 << UCSZ00); /* 8N1 */
51
52   UBRR0L = (int8_t) (F_CPU/(r*8L)-1);
53   UBRR0H = (F_CPU/(r*8L)-1) >> 8;
54
55   return;
56
57 }
58
59
60 void zigduino_init_uart0(){
61   setbaud0(0);
62   _delay_ms(500); //takes a bit to stabilize
63 }
64
65 void led_init(){
66
67   PLEDDIR |= (1 << PLEDPIN);
68 }
69
70 void  led_on() {
71   PLEDOUT |= (1 << PLEDPIN);
72 }
73
74 void led_off() {
75   PLEDOUT &= ~(1 << PLEDPIN);
76 }
77
78 void zigduino_init(){
79   uint8_t x;
80
81   /* explicitly clear interrupts */
82   cli();
83
84   /* move the vectors */
85
86   /* move interrupts from boot flash section */
87   /* NB */
88   /* you MUST use a variable during this process. even highly optimized,
89    * masking the bit, shifting, ANDing, and setting MCUCR will exceed
90    * 4 CPU cycles! set a variable with the desired value for MCUCR and
91    * then set the register once IVCE is enabled
92    */
93   x = MCUCR & ~(1 << IVSEL);
94
95   /* enable change of interrupt vectors */
96   /* NOTE: setting IVCE disables interrupts until the bit is auto-unset
97    * 4 cycles after being set or after IVSEL is written
98    */
99   MCUCR |= (1 << IVCE);
100   MCUCR = x;
101
102   /* disable the watchdog timer; this macro will disable interrupts for us */
103   /* NOTE: ensure that the WDRF flag is unset in the MCUSR or we will spinlock
104    * when the watchdog times out
105    */
106   MCUSR &= ~(1 << WDRF);
107   wdt_disable();
108
109   /* init the USART */
110   zigduino_init_uart0();
111
112   /* set the LED as an output */
113   led_init();
114
115   /* enable internal internal pull-up resister
116         in order to supress line noise that prevents
117         bootloader from timing out */
118   SPIDIR &= ~(1 << SPIPIN);
119   SPIOUT |= (1 << SPIPIN);
120
121   /* explicitly enable interrupts */
122   sei();
123
124 }
125
126 void
127 zigduino_reboot()
128 {
129   MCUSR &= ~(1 << WDRF);
130   wdt_enable(WDTO_15MS);
131   while(1)
132     _delay_ms(127);
133 }
134
135 int *
136 zigduino_ramend(void)
137 {
138   /* NB */
139   /* ATmega128rfa1 has 16K SRAM */
140   return (int * )0x4000;
141 }
142
143 void
144 led_toggle(void)
145 {
146   led_on();
147   _delay_ms(30);
148   led_off();
149 }