new global_logger, used in AVR_LOG(), default is stdout/stderr
[simavr] / simavr / cores / sim_tiny2313.c
1 /*
2         sim_tiny2313.c
3
4         Copyright 2008, 2009 Michel Pollet <buserror@gmail.com>
5
6         This file is part of simavr.
7
8         simavr is free software: you can redistribute it and/or modify
9         it under the terms of the GNU General Public License as published by
10         the Free Software Foundation, either version 3 of the License, or
11         (at your option) any later version.
12
13         simavr is distributed in the hope that it will be useful,
14         but WITHOUT ANY WARRANTY; without even the implied warranty of
15         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16         GNU General Public License for more details.
17
18         You should have received a copy of the GNU General Public License
19         along with simavr.  If not, see <http://www.gnu.org/licenses/>.
20  */
21
22 #include "sim_core_declare.h"
23 #include "avr_eeprom.h"
24 #include "avr_watchdog.h"
25 #include "avr_extint.h"
26 #include "avr_ioport.h"
27 #include "avr_uart.h"
28 #include "avr_timer.h"
29
30 static void init(struct avr_t * avr);
31 static void reset(struct avr_t * avr);
32
33 #define _AVR_IO_H_
34 #define __ASSEMBLER__
35 #include "avr/iotn2313.h"
36
37 /*
38  * This is a template for all of the tinyx5 devices, hopefully
39  */
40 static const struct mcu_t {
41         avr_t core;
42         avr_eeprom_t    eeprom;
43         avr_watchdog_t  watchdog;
44         avr_extint_t    extint;
45         avr_ioport_t    porta, portb, portd;
46         avr_uart_t              uart;
47         avr_timer_t             timer0,timer1;
48 } mcu = {
49         .core = {
50                 .mmcu = "attiny2313",
51                 DEFAULT_CORE(2),
52
53                 .init = init,
54                 .reset = reset,
55         },
56         AVR_EEPROM_DECLARE_8BIT(EEPROM_READY_vect),
57         AVR_WATCHDOG_DECLARE(WDTCSR, WDT_OVERFLOW_vect),
58         .extint = {
59                 AVR_EXTINT_TINY_DECLARE(0, 'D', 2, EIFR),
60                 AVR_EXTINT_TINY_DECLARE(1, 'D', 3, EIFR),
61         },
62         .porta = {      // port A has no PCInts..
63                 .name = 'A', .r_port = PORTA, .r_ddr = DDRA, .r_pin = PINA,
64         },
65         .portb = {
66                 .name = 'B',  .r_port = PORTB, .r_ddr = DDRB, .r_pin = PINB,
67                 .pcint = {
68                         .enable = AVR_IO_REGBIT(GIMSK, PCIE),
69                         .raised = AVR_IO_REGBIT(EIFR, PCIF),
70                         .vector = PCINT_vect,
71                 },
72                 .r_pcint = PCMSK,
73         },
74         .portd = {      // port D has no PCInts..
75                 .name = 'D', .r_port = PORTD, .r_ddr = DDRD, .r_pin = PIND,
76         },
77         .uart = {
78                 // no PRR register on the 2313
79                 //.disabled = AVR_IO_REGBIT(PRR,PRUSART0),
80                 .name = '0',
81                 .r_udr = UDR,
82
83                 .txen = AVR_IO_REGBIT(UCSRB, TXEN),
84                 .rxen = AVR_IO_REGBIT(UCSRB, RXEN),
85                 .ucsz = AVR_IO_REGBITS(UCSRC, UCSZ0, 0x3), // 2 bits
86                 .ucsz2 = AVR_IO_REGBIT(UCSRB, UCSZ2),   // 1 bits
87
88                 .r_ucsra = UCSRA,
89                 .r_ucsrb = UCSRB,
90                 .r_ucsrc = UCSRC,
91                 .r_ubrrl = UBRRL,
92                 .r_ubrrh = UBRRH,
93                 .rxc = {
94                         .enable = AVR_IO_REGBIT(UCSRB, RXCIE),
95                         .raised = AVR_IO_REGBIT(UCSRA, RXC),
96                         .vector = USART_RX_vect,
97                 },
98                 .txc = {
99                         .enable = AVR_IO_REGBIT(UCSRB, TXCIE),
100                         .raised = AVR_IO_REGBIT(UCSRA, TXC),
101                         .vector = USART_TX_vect,
102                 },
103                 .udrc = {
104                         .enable = AVR_IO_REGBIT(UCSRB, UDRIE),
105                         .raised = AVR_IO_REGBIT(UCSRA, UDRE),
106                         .vector = USART_UDRE_vect,
107                 },
108         },
109         .timer0 = {
110                 .name = '0',
111                 .wgm = { AVR_IO_REGBIT(TCCR0A, WGM00), AVR_IO_REGBIT(TCCR0A, WGM01), AVR_IO_REGBIT(TCCR0B, WGM02) },
112                 .wgm_op = {
113                         [0] = AVR_TIMER_WGM_NORMAL8(),
114                         [2] = AVR_TIMER_WGM_CTC(),
115                         [3] = AVR_TIMER_WGM_FASTPWM8(),
116                         [7] = AVR_TIMER_WGM_OCPWM(),
117                 },
118                 .cs = { AVR_IO_REGBIT(TCCR0B, CS00), AVR_IO_REGBIT(TCCR0B, CS01), AVR_IO_REGBIT(TCCR0B, CS02) },
119                 .cs_div = { 0, 0, 3 /* 8 */, 6 /* 64 */, 8 /* 256 */, 10 /* 1024 */ },
120
121                 .r_tcnt = TCNT0,
122
123                 .overflow = {
124                         .enable = AVR_IO_REGBIT(TIMSK, TOIE0),
125                         .raised = AVR_IO_REGBIT(TIFR, TOV0),
126                         .vector = TIMER0_OVF_vect,
127                 },
128                 .comp = {
129                         [AVR_TIMER_COMPA] = {
130                                 .r_ocr = OCR0A,
131                                 .com = AVR_IO_REGBITS(TCCR0A, COM0A0, 0x3),
132                                 .com_pin = AVR_IO_REGBIT(PORTB, 2),
133                                 .interrupt = {
134                                         .enable = AVR_IO_REGBIT(TIMSK, OCIE0A),
135                                         .raised = AVR_IO_REGBIT(TIFR, OCF0A),
136                                         .vector = TIMER0_COMPA_vect,
137                                 },
138                         },
139                         [AVR_TIMER_COMPB] = {
140                                 .r_ocr = OCR0B,
141                                 .com = AVR_IO_REGBITS(TCCR0A, COM0B0, 0x3),
142                                 .com_pin = AVR_IO_REGBIT(PORTD, 5),
143                                 .interrupt = {
144                                         .enable = AVR_IO_REGBIT(TIMSK, OCIE0B),
145                                         .raised = AVR_IO_REGBIT(TIFR, OCF0B),
146                                         .vector = TIMER0_COMPB_vect,
147                                 }
148                         }
149                 },
150         },
151         .timer1 = {
152                 .name = '1',
153         //      .disabled = AVR_IO_REGBIT(PRR,PRTIM1),
154                 .wgm = { AVR_IO_REGBIT(TCCR1A, WGM10), AVR_IO_REGBIT(TCCR1A, WGM11),
155                                         AVR_IO_REGBIT(TCCR1B, WGM12), AVR_IO_REGBIT(TCCR1B, WGM13) },
156                 .wgm_op = {
157                         [0] = AVR_TIMER_WGM_NORMAL16(),
158                         [4] = AVR_TIMER_WGM_CTC(),
159                         [5] = AVR_TIMER_WGM_FASTPWM8(),
160                         [6] = AVR_TIMER_WGM_FASTPWM9(),
161                         [7] = AVR_TIMER_WGM_FASTPWM10(),
162                         [12] = AVR_TIMER_WGM_ICCTC(),
163                         [14] = AVR_TIMER_WGM_ICPWM(),
164                         [15] = AVR_TIMER_WGM_OCPWM(),
165                 },
166                 .cs = { AVR_IO_REGBIT(TCCR1B, CS10), AVR_IO_REGBIT(TCCR1B, CS11), AVR_IO_REGBIT(TCCR1B, CS12) },
167                 .cs_div = { 0, 0, 3 /* 8 */, 6 /* 64 */, 8 /* 256 */, 10 /* 1024 */  /* External clock T1 is not handled */},
168
169                 .r_tcnt = TCNT1L,
170                 .r_icr = ICR1L,
171                 .r_icrh = ICR1H,
172                 .r_tcnth = TCNT1H,
173
174                 .ices = AVR_IO_REGBIT(TCCR1B, ICES1),
175                 .icp = AVR_IO_REGBIT(PORTD, 6),
176
177                 .overflow = {
178                         .enable = AVR_IO_REGBIT(TIMSK, TOIE1),
179                         .raised = AVR_IO_REGBIT(TIFR, TOV1),
180                         .vector = TIMER1_OVF_vect,
181                 },
182                 .icr = {
183                         .enable = AVR_IO_REGBIT(TIMSK, ICIE1),
184                         .raised = AVR_IO_REGBIT(TIFR, ICF1),
185                         .vector = TIMER1_CAPT_vect,
186                 },
187                 .comp = {
188                         [AVR_TIMER_COMPA] = {
189                                 .r_ocr = OCR1AL,
190                                 .r_ocrh = OCR1AH,       // 16 bits timers have two bytes of it
191                                 .com = AVR_IO_REGBITS(TCCR1A, COM1A0, 0x3),
192                                 .com_pin = AVR_IO_REGBIT(PORTB, 3),
193                                 .interrupt = {
194                                         .enable = AVR_IO_REGBIT(TIMSK, OCIE1A),
195                                         .raised = AVR_IO_REGBIT(TIFR, OCF1A),
196                                         .vector = TIMER1_COMPA_vect,
197                                 },
198                         },
199                         [AVR_TIMER_COMPB] = {
200                                 .r_ocr = OCR1BL,
201                                 .r_ocrh = OCR1BH,
202                                 .com = AVR_IO_REGBITS(TCCR1A, COM1A0, 0x3),
203                                 .com_pin = AVR_IO_REGBIT(PORTB, 4),
204                                 .interrupt = {
205                                         .enable = AVR_IO_REGBIT(TIMSK, OCIE1B),
206                                         .raised = AVR_IO_REGBIT(TIFR, OCF1B),
207                                         .vector = TIMER1_COMPB_vect,
208                                 }
209                         }
210                 }
211         }
212 };
213
214 static avr_t * make()
215 {
216         return avr_core_allocate(&mcu.core, sizeof(struct mcu_t));
217 }
218
219 avr_kind_t tiny2313 = {
220         .names = { "attiny2313", "attiny2313v" },
221         .make = make
222 };
223
224 static void init(struct avr_t * avr)
225 {
226         struct mcu_t * mcu = (struct mcu_t*)avr;
227
228         avr_eeprom_init(avr, &mcu->eeprom);
229         avr_watchdog_init(avr, &mcu->watchdog);
230         avr_extint_init(avr, &mcu->extint);
231         avr_ioport_init(avr, &mcu->porta);
232         avr_ioport_init(avr, &mcu->portb);
233         avr_ioport_init(avr, &mcu->portd);
234         avr_uart_init(avr, &mcu->uart);
235         avr_timer_init(avr, &mcu->timer0);
236         avr_timer_init(avr, &mcu->timer1);
237 }
238
239 static void reset(struct avr_t * avr)
240 {
241 //      struct mcu_t * mcu = (struct mcu_t*)avr;
242 }
243