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