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