00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include <config.h>
00032
00033 #include <stdio.h>
00034 #include <stdlib.h>
00035 #include <string.h>
00036
00037 #include "avrerror.h"
00038 #include "avrmalloc.h"
00039 #include "avrclass.h"
00040 #include "utils.h"
00041 #include "callback.h"
00042 #include "op_names.h"
00043
00044 #include "storage.h"
00045 #include "flash.h"
00046
00047 #include "vdevs.h"
00048 #include "memory.h"
00049 #include "stack.h"
00050 #include "register.h"
00051 #include "sram.h"
00052 #include "eeprom.h"
00053 #include "timers.h"
00054 #include "ports.h"
00055 #include "uart.h"
00056
00057 #include "avrcore.h"
00058
00059 #include "intvects.h"
00060
00061
00062
00063
00064
00065
00066
00067 static void uart_iadd_addr (VDevice *vdev, int addr, char *name, int rel_addr,
00068 void *data);
00069 static uint8_t uart_intr_read (VDevice *dev, int addr);
00070 static void uart_intr_write (VDevice *dev, int addr, uint8_t val);
00071 static void uart_intr_reset (VDevice *dev);
00072 static int uart_intr_cb (uint64_t time, AvrClass *data);
00073
00074 unsigned int UART_Int_Table[] = {
00075 irq_vect_table_index (UART_RX),
00076 irq_vect_table_index (UART_UDRE),
00077 irq_vect_table_index (UART_TX)
00078 };
00079
00080 unsigned int UART0_Int_Table[] = {
00081 irq_vect_table_index (USART0_RX),
00082 irq_vect_table_index (USART0_UDRE),
00083 irq_vect_table_index (USART0_TX)
00084 };
00085
00086 unsigned int UART1_Int_Table[] = {
00087 irq_vect_table_index (USART1_RX),
00088 irq_vect_table_index (USART1_UDRE),
00089 irq_vect_table_index (USART1_TX)
00090 };
00091
00092
00093
00094 VDevice *
00095 uart_int_create (int addr, char *name, int rel_addr, void *data)
00096 {
00097 if (data)
00098 return (VDevice *)uart_intr_new (addr, name, data);
00099 else
00100 avr_error ("Attempted UART create with NULL data pointer");
00101 return 0;
00102 }
00103
00104 UARTIntr_T *
00105 uart_intr_new (int addr, char *name, void *data)
00106 {
00107 uint8_t *uart_num = (uint8_t *) data;
00108 UARTIntr_T *uart;
00109
00110 uart = avr_new (UARTIntr_T, 1);
00111 uart_intr_construct (uart, addr, name);
00112 class_overload_destroy ((AvrClass *)uart, uart_intr_destroy);
00113
00114 if (*uart_num == USART0)
00115 uart->Int_Table = &UART0_Int_Table[0];
00116 else if (*uart_num == USART1)
00117 uart->Int_Table = &UART1_Int_Table[0];
00118 else
00119 uart->Int_Table = &UART_Int_Table[0];
00120
00121 uart_iadd_addr ((VDevice *)uart, addr, name, 0, NULL);
00122 return uart;
00123 }
00124
00125
00126
00127 void
00128 uart_intr_construct (UARTIntr_T *uart, int addr, char *name)
00129 {
00130 if (uart == NULL)
00131 avr_error ("passed null ptr");
00132
00133 vdev_construct ((VDevice *)uart, uart_intr_read, uart_intr_write,
00134 uart_intr_reset, uart_iadd_addr);
00135
00136 uart_intr_reset ((VDevice *)uart);
00137 }
00138
00139 static void
00140 uart_iadd_addr (VDevice *vdev, int addr, char *name, int rel_addr, void *data)
00141 {
00142 UARTIntr_T *uart = (UARTIntr_T *)vdev;
00143
00144 if (strncmp ("UBRRH", name, 5) == 0)
00145 {
00146 uart->ubrrh_addr = addr;
00147 }
00148
00149 else if ((strncmp ("UBRR", name, 4) == 0)
00150 || (strncmp ("UBRR0", name, 5) == 0)
00151 || (strncmp ("UBRR1", name, 5) == 0))
00152 {
00153 uart->ubrrl_addr = addr;
00154 }
00155
00156 else if ((strncmp ("USR", name, 3) == 0)
00157 || (strncmp ("UCSR0A", name, 6) == 0)
00158 || (strncmp ("UCSR1A", name, 6) == 0))
00159 {
00160 uart->usr_addr = addr;
00161 }
00162
00163 else if ((strncmp ("UCR", name, 3) == 0)
00164 || (strncmp ("UCSR0B", name, 6) == 0)
00165 || (strncmp ("UCSR1B", name, 6) == 0))
00166 {
00167 uart->ucr_addr = addr;
00168 }
00169
00170 else
00171 {
00172 avr_error ("invalid UART register name: '%s' @ 0x%04x", name, addr);
00173 }
00174 }
00175
00176
00177
00178 void
00179 uart_intr_destroy (void *uart)
00180 {
00181 if (uart == NULL)
00182 return;
00183
00184 vdev_destroy (uart);
00185 }
00186
00187 static uint8_t
00188 uart_intr_read (VDevice *dev, int addr)
00189 {
00190 UARTIntr_T *uart = (UARTIntr_T *)dev;
00191
00192 if (addr == uart->ubrrl_addr)
00193 {
00194 return (uart->ubrr & 0xff);
00195 }
00196
00197 else if (addr == uart->ubrrh_addr)
00198 {
00199 return (uart->ubrr >> 8);
00200 }
00201
00202 else if (addr == uart->ucr_addr)
00203 {
00204 return (uart->ucr);
00205 }
00206
00207 else if (addr == uart->usr_addr)
00208 {
00209 return (uart->usr);
00210 }
00211
00212 else
00213 {
00214 avr_error ("Bad address: 0x%04x", addr);
00215 }
00216
00217 return 0;
00218 }
00219
00220 static void
00221 uart_intr_write (VDevice *dev, int addr, uint8_t val)
00222 {
00223 UARTIntr_T *uart = (UARTIntr_T *)dev;
00224 CallBack *cb;
00225
00226 if (addr == uart->ubrrl_addr)
00227 {
00228 uart->ubrr = val + (uart->ubrr_temp << 8);
00229 }
00230
00231 else if (addr == uart->ubrrh_addr)
00232 {
00233 uart->ubrr_temp = val;
00234 }
00235
00236 else if (addr == uart->usr)
00237 {
00238 if (val & mask_TXC)
00239 uart->usr &= ~mask_TXC;
00240 }
00241
00242 else if (addr == uart->ucr_addr)
00243 {
00244 (uart->ucr = val);
00245
00246 if (((uart->ucr & mask_TXEN) && (uart->ucr & mask_TXCIE))
00247 || ((uart->ucr & mask_RXEN) && (uart->ucr & mask_RXCIE))
00248 || (uart->ucr & mask_UDRIE))
00249 {
00250 if (uart->intr_cb == NULL)
00251 {
00252
00253 cb = callback_new (uart_intr_cb, (AvrClass *)uart);
00254 uart->intr_cb = cb;
00255 avr_core_async_cb_add ((AvrCore *)vdev_get_core (dev), cb);
00256 }
00257 }
00258 else
00259 {
00260 uart->intr_cb = NULL;
00261
00262 }
00263 }
00264
00265 else
00266 {
00267 avr_error ("Bad address: 0x%04x", addr);
00268 }
00269 }
00270
00271 static void
00272 uart_intr_reset (VDevice *dev)
00273 {
00274 UARTIntr_T *uart = (UARTIntr_T *)dev;
00275
00276 uart->intr_cb = NULL;
00277
00278 uart->ubrr = 0;
00279 uart->usr = 0;
00280 uart->ucr = 0;
00281 uart->usr_shadow = 0;
00282 }
00283
00284 static int
00285 uart_intr_cb (uint64_t time, AvrClass *data)
00286 {
00287 UARTIntr_T *uart = (UARTIntr_T *)data;
00288
00289 if (uart->intr_cb == NULL)
00290 return CB_RET_REMOVE;
00291
00292 if ((uart->ucr & mask_RXCIE) && (uart->usr & mask_RXC))
00293
00294 {
00295 AvrCore *core = (AvrCore *)vdev_get_core ((VDevice *)uart);
00296 avr_core_irq_raise (core, (uart->Int_Table[URX]));
00297 }
00298
00299 if ((uart->ucr & mask_TXCIE) && (uart->usr & mask_TXC))
00300
00301 {
00302 AvrCore *core = (AvrCore *)vdev_get_core ((VDevice *)uart);
00303 avr_core_irq_raise (core, (uart->Int_Table[UTX]));
00304 uart->usr &= ~mask_TXC;
00305 }
00306
00307 if ((uart->ucr & mask_UDRIE) && (uart->usr & mask_UDRE)
00308 && (uart->usr_shadow & mask_UDRE))
00309
00310 {
00311 AvrCore *core = (AvrCore *)vdev_get_core ((VDevice *)uart);
00312 avr_core_irq_raise (core, (uart->Int_Table[UUDRE]));
00313 uart->usr_shadow &= ~mask_UDRE;
00314 }
00315
00316 return CB_RET_RETAIN;
00317 }
00318
00319
00320
00321
00322
00323
00324
00325 static void uart_add_addr (VDevice *vdev, int addr, char *name, int rel_addr,
00326 void *data);
00327 static uint8_t uart_read (VDevice *dev, int addr);
00328 static void uart_write (VDevice *dev, int addr, uint8_t val);
00329 static void uart_reset (VDevice *dev);
00330 static int uart_clk_incr_cb (uint64_t ck, AvrClass *data);
00331
00332
00333
00334 VDevice *
00335 uart_create (int addr, char *name, int rel_addr, void *data)
00336 {
00337 return (VDevice *)uart_new (addr, name, rel_addr);
00338 }
00339
00340 UART_T *
00341 uart_new (int addr, char *name, int rel_addr)
00342 {
00343 UART_T *uart;
00344
00345 uart = avr_new (UART_T, 1);
00346 uart_construct (uart, addr, name, rel_addr);
00347
00348 class_overload_destroy ((AvrClass *)uart, uart_destroy);
00349
00350 return uart;
00351 }
00352
00353
00354
00355 void
00356 uart_construct (UART_T *uart, int addr, char *name, int rel_addr)
00357 {
00358 if (uart == NULL)
00359 avr_error ("passed null ptr");
00360
00361 vdev_construct ((VDevice *)uart, uart_read, uart_write, uart_reset,
00362 uart_add_addr);
00363
00364 uart_add_addr ((VDevice *)uart, addr, name, 0, NULL);
00365 if (rel_addr)
00366 uart->related_addr = rel_addr;
00367 uart_reset ((VDevice *)uart);
00368 }
00369
00370 static void
00371 uart_add_addr (VDevice *vdev, int addr, char *name, int ref_addr, void *data)
00372 {
00373 UART_T *uart = (UART_T *)vdev;
00374
00375 if (strncmp ("UDR", name, 3) == 0)
00376 {
00377 uart->udr_addr = addr;
00378 }
00379
00380 else
00381 {
00382 avr_error ("invalid SPI register name: '%s' @ 0x%04x", name, addr);
00383 }
00384 }
00385
00386
00387
00388 void
00389 uart_destroy (void *uart)
00390 {
00391 if (uart == NULL)
00392 return;
00393
00394 vdev_destroy (uart);
00395 }
00396
00397 static uint8_t
00398 uart_read (VDevice *dev, int addr)
00399 {
00400 UART_T *uart = (UART_T *)dev;
00401 UARTIntr_T *uart_t;
00402 uint16_t udr_temp;
00403
00404 uart_t =
00405 (UARTIntr_T *)avr_core_get_vdev_by_addr ((AvrCore *)
00406 vdev_get_core ((VDevice *)
00407 uart),
00408 uart->related_addr);
00409
00410 if (addr == uart->udr_addr)
00411 {
00412 uart_t->usr &= ~mask_RXC;
00413 if (uart->clk_cb)
00414 {
00415 udr_temp = uart_port_rd (addr);
00416 uart->udr_rx = (uint8_t) udr_temp;
00417 if ((uart_t->ucr & mask_CHR9) &&
00418 (udr_temp & (1 << 8)))
00419 uart_t->ucr |= mask_RXB8;
00420 else
00421 uart_t->ucr &= ~mask_RXB8;
00422 }
00423 return uart->udr_rx;
00424 }
00425
00426 else
00427 {
00428 avr_error ("Bad address: 0x%04x", addr);
00429 }
00430
00431 return 0;
00432 }
00433
00434 static void
00435 uart_write (VDevice *dev, int addr, uint8_t val)
00436 {
00437 UART_T *uart = (UART_T *)dev;
00438 UARTIntr_T *uart_t;
00439 CallBack *cb;
00440
00441 uart_t =
00442 (UARTIntr_T *)avr_core_get_vdev_by_addr ((AvrCore *)
00443 vdev_get_core ((VDevice *)
00444 uart),
00445 uart->related_addr);
00446
00447 if (addr == uart->udr_addr)
00448 {
00449 if (uart_t->usr & mask_UDRE)
00450 {
00451 uart_t->usr &= ~mask_UDRE;
00452 uart_t->usr_shadow &= ~mask_UDRE;
00453 }
00454 else
00455 {
00456 uart_t->usr |= mask_UDRE;
00457 uart_t->usr_shadow |= mask_UDRE;
00458 }
00459 uart->udr_tx = val;
00460
00461
00462
00463
00464
00465
00466 uart->divisor = (uart_t->ubrr + 1) * 16;
00467
00468
00469
00470 if (uart->clk_cb == NULL)
00471 {
00472 cb = callback_new (uart_clk_incr_cb, (AvrClass *)uart);
00473 uart->clk_cb = cb;
00474 avr_core_clk_cb_add ((AvrCore *)vdev_get_core ((VDevice *)uart),
00475 cb);
00476 }
00477
00478
00479
00480
00481 uart->tcnt = (uart_t->ucr & mask_CHR9) ? 11 : 10;
00482 }
00483
00484 else
00485 {
00486 avr_error ("Bad address: 0x%04x", addr);
00487 }
00488 }
00489
00490 static void
00491 uart_reset (VDevice *dev)
00492 {
00493 UART_T *uart = (UART_T *)dev;
00494
00495 uart->clk_cb = NULL;
00496
00497 uart->udr_rx = 0;
00498 uart->udr_tx = 0;
00499 uart->tcnt = 0;
00500 uart->divisor = 0;
00501 }
00502
00503 static int
00504 uart_clk_incr_cb (uint64_t ck, AvrClass *data)
00505 {
00506 UART_T *uart = (UART_T *)data;
00507 UARTIntr_T *uart_t;
00508 uint8_t last = uart->tcnt;
00509
00510 uart_t =
00511 (UARTIntr_T *)avr_core_get_vdev_by_addr ((AvrCore *)
00512 vdev_get_core ((VDevice *)
00513 uart),
00514 uart->related_addr);
00515
00516 if (uart->clk_cb == NULL)
00517 return CB_RET_REMOVE;
00518
00519 if (uart->divisor <= 0)
00520 avr_error ("Bad divisor value: %d", uart->divisor);
00521
00522
00523
00524 uart->tcnt -= ((ck % uart->divisor) == 0);
00525
00526 if (uart->tcnt != last)
00527 {
00528 if (uart->tcnt == 0)
00529 {
00530 if (uart_t->usr & mask_UDRE)
00531 {
00532 uart_t->usr |= mask_TXC;
00533 uart->clk_cb = NULL;
00534 return CB_RET_REMOVE;
00535 }
00536 else
00537 {
00538 uart_t->usr |= mask_UDRE;
00539 uart_t->usr_shadow |= mask_UDRE;
00540
00541
00542
00543
00544 uart->tcnt = (uart_t->ucr & mask_CHR9) ? 11 : 10;
00545 }
00546 }
00547 }
00548
00549 return CB_RET_RETAIN;
00550 }
00551
00552 uint16_t
00553 uart_port_rd (int addr)
00554 {
00555 int data;
00556 char line[80];
00557
00558 while (1)
00559 {
00560 fprintf (stderr,
00561 "\nEnter 9 bits of hex data to read into the uart at "
00562 "address 0x%04x: ", addr);
00563
00564
00565 if (fgets (line, sizeof (line), stdin) == NULL)
00566 continue;
00567
00568
00569 if (sscanf (line, "%x\n", &data) != 1)
00570 continue;
00571
00572 break;
00573 }
00574
00575 return (uint16_t) (data & 0x1ff);
00576 }
00577
00578 void
00579 uart_port_wr (uint8_t val)
00580 {
00581 fprintf (stderr, "wrote 0x%02x to uart\n", val);
00582 }