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
00032
#include <config.h>
00033
00034
#include <stdio.h>
00035
#include <stdlib.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 "adc.h"
00056
00057
#include "avrcore.h"
00058
00059
#include "intvects.h"
00060
00061
00062
00063
00064
00065
00066
00067
static uint8_t adc_intr_read (VDevice *dev,
int addr);
00068
static void adc_intr_write (VDevice *dev,
int addr, uint8_t val);
00069
static void adc_intr_reset (VDevice *dev);
00070
static char *adc_intr_reg_name (VDevice *dev,
int addr);
00071
static int adc_intr_cb (uint64_t time, AvrClass *data);
00072
static int adc_clk_incr_cb (uint64_t ck, AvrClass *data);
00073
00074
00075
00076 ADCIntr_T *
00077 adc_intr_new (uint8_t uier)
00078 {
00079 ADCIntr_T *adc;
00080
00081 adc =
avr_new (ADCIntr_T, 1);
00082
adc_intr_construct (adc, uier);
00083
class_overload_destroy ((AvrClass *)adc,
adc_intr_destroy);
00084
00085
return adc;
00086 }
00087
00088
00089
00090
void
00091 adc_intr_construct (ADCIntr_T *adc, uint8_t uier)
00092 {
00093
char *name =
"ADCIntr";
00094
00095
if (adc == NULL)
00096
avr_error (
"passed null ptr");
00097
00098
if (uier)
00099
vdev_construct ((VDevice *)adc, name, ADC_INTR_BASE_U, ADC_INTR_SIZE,
00100 adc_intr_read, adc_intr_write, adc_intr_reset,
00101 adc_intr_reg_name);
00102
else
00103
vdev_construct ((VDevice *)adc, name, ADC_INTR_BASE_A, ADC_INTR_SIZE,
00104 adc_intr_read, adc_intr_write, adc_intr_reset,
00105 adc_intr_reg_name);
00106
00107 adc_intr_reset ((VDevice *)adc);
00108 }
00109
00110
00111
00112
void
00113 adc_intr_destroy (
void *adc)
00114 {
00115
if (adc == NULL)
00116
return;
00117
00118
vdev_destroy (adc);
00119 }
00120
00121
static uint8_t
00122 adc_intr_read (VDevice *dev,
int addr)
00123 {
00124 ADCIntr_T *adc = (ADCIntr_T *)dev;
00125
00126
switch (addr -
vdev_get_base (dev))
00127 {
00128
case ADC_INTR_ADCSR_ADDR:
00129
return (adc->adcsr);
00130
case ADC_INTR_ADMUX_ADDR:
00131
return (adc->admux);
00132
default:
00133
avr_error (
"Bad address: 0x%04x", addr);
00134 }
00135
return 0;
00136 }
00137
00138
static void
00139 adc_intr_write (VDevice *dev,
int addr, uint8_t val)
00140 {
00141 ADCIntr_T *adc = (ADCIntr_T *)dev;
00142 CallBack *cb;
00143 ADC_T *adc_d;
00144
00145 adc_d =
00146 (ADC_T *)
avr_core_get_vdev_by_name ((AvrCore *)
00147 vdev_get_core ((VDevice *)adc),
00148
"ADC");
00149
00150
switch (addr -
vdev_get_base (dev))
00151 {
00152
case ADC_INTR_ADCSR_ADDR:
00153
if (val & mask_ADIF)
00154 adc->adcsr = val & ~mask_ADIF;
00155
else
00156 adc->adcsr = val;
00157
00158
if ((val & mask_ADSC) && (val & mask_ADEN))
00159 {
00160
if ((adc->intr_cb == NULL))
00161 {
00162
00163 cb = callback_new (adc_intr_cb, (AvrClass *)adc);
00164 adc->intr_cb = cb;
00165
avr_core_async_cb_add ((AvrCore *)vdev_get_core (dev),
00166 cb);
00167 }
00168
if ((adc_d->clk_cb == NULL))
00169 {
00170
00171 cb = callback_new (adc_clk_incr_cb, (AvrClass *)adc_d);
00172 adc_d->clk_cb = cb;
00173
avr_core_clk_cb_add ((AvrCore *)vdev_get_core (dev), cb);
00174 }
00175 adc_d->adc_count = 13;
00176
switch ((adc->adcsr) & (mask_ADPS0 | mask_ADPS1 | mask_ADPS2))
00177 {
00178
case ADC_CK_0:
00179
case ADC_CK_2:
00180 adc_d->divisor = 2;
00181
break;
00182
case ADC_CK_4:
00183 adc_d->divisor = 4;
00184
break;
00185
case ADC_CK_8:
00186 adc_d->divisor = 8;
00187
break;
00188
case ADC_CK_16:
00189 adc_d->divisor = 16;
00190
break;
00191
case ADC_CK_32:
00192 adc_d->divisor = 32;
00193
break;
00194
case ADC_CK_64:
00195 adc_d->divisor = 64;
00196
break;
00197
case ADC_CK_128:
00198 adc_d->divisor = 128;
00199
break;
00200
default:
00201
avr_error (
"The impossible happened!");
00202 }
00203 }
00204
else
00205 {
00206 adc->intr_cb = NULL;
00207
00208 }
00209
break;
00210
case ADC_INTR_ADMUX_ADDR:
00211 adc->admux = val;
00212
break;
00213
default:
00214
avr_error (
"Bad address: 0x%04x", addr);
00215 }
00216 }
00217
00218
static void
00219 adc_intr_reset (VDevice *dev)
00220 {
00221 ADCIntr_T *adc = (ADCIntr_T *)dev;
00222
00223 adc->intr_cb = NULL;
00224
00225 adc->adcsr = 0;
00226 adc->admux = 0;
00227 }
00228
00229
static char *
00230 adc_intr_reg_name (VDevice *dev,
int addr)
00231 {
00232
switch (addr -
vdev_get_base (dev))
00233 {
00234
case ADC_INTR_ADCSR_ADDR:
00235
return (
"ADSCR");
00236
case ADC_INTR_ADMUX_ADDR:
00237
return (
"ADMUX");
00238
default:
00239
avr_error (
"Bad address: 0x%04x", addr);
00240 }
00241
return NULL;
00242 }
00243
00244
static int
00245 adc_intr_cb (uint64_t time, AvrClass *data)
00246 {
00247 ADCIntr_T *adc = (ADCIntr_T *)data;
00248
00249
if (adc->intr_cb == NULL)
00250
return CB_RET_REMOVE;
00251
00252
if ((adc->adcsr & mask_ADEN) && (adc->adcsr & mask_ADIE)
00253 && (adc->adcsr & mask_ADIF))
00254 {
00255
00256 AvrCore *core = (AvrCore *)
vdev_get_core ((VDevice *)adc);
00257
avr_core_irq_raise (core, irq_vect_table_index (ADC));
00258 adc->adcsr &= ~mask_ADIF;
00259 }
00260
00261
return CB_RET_RETAIN;
00262 }
00263
00264
00265
00266
00267
00268
00269
00270
static uint8_t adc_read (VDevice *dev,
int addr);
00271
static void adc_write (VDevice *dev,
int addr, uint8_t val);
00272
static void adc_reset (VDevice *dev);
00273
static char *adc_reg_name (VDevice *dev,
int addr);
00274
00275
00276
00277 ADC_T *
00278 adc_new (uint8_t uier)
00279 {
00280 ADC_T *adc;
00281
00282 adc =
avr_new (ADC_T, 1);
00283
adc_construct (adc, uier);
00284
class_overload_destroy ((AvrClass *)adc,
adc_destroy);
00285
00286
return adc;
00287 }
00288
00289
00290
00291
void
00292 adc_construct (ADC_T *adc, uint8_t uier)
00293 {
00294
char *name =
"ADC";
00295
00296
if (adc == NULL)
00297
avr_error (
"passed null ptr");
00298
00299
if (uier)
00300
vdev_construct ((VDevice *)adc, name, ADC_BASE_U, ADC_SIZE, adc_read,
00301 adc_write, adc_reset, adc_reg_name);
00302
else
00303
vdev_construct ((VDevice *)adc, name, ADC_BASE_A, ADC_SIZE, adc_read,
00304 adc_write, adc_reset, adc_reg_name);
00305
00306 adc_reset ((VDevice *)adc);
00307 adc->u_divisor = uier ? 12 : 1;
00308 }
00309
00310
00311
00312
void
00313 adc_destroy (
void *adc)
00314 {
00315
if (adc == NULL)
00316
return;
00317
00318
vdev_destroy (adc);
00319 }
00320
00321
static uint8_t
00322 adc_read (VDevice *dev,
int addr)
00323 {
00324 ADC_T *adc = (ADC_T *)dev;
00325
00326
switch (addr -
vdev_get_base (dev))
00327 {
00328
case ADC_ADCL_ADDR:
00329
return adc->adcl;
00330
case ADC_ADCH_ADDR:
00331
return adc->adch;
00332
default:
00333
avr_error (
"Bad address: 0x%04x", addr);
00334 }
00335
return 0;
00336 }
00337
00338
static void
00339 adc_write (VDevice *dev,
int addr, uint8_t val)
00340 {
00341
avr_error (
"Bad ADC write address: 0x%04x", addr);
00342 }
00343
00344
static void
00345 adc_reset (VDevice *dev)
00346 {
00347 ADC_T *adc = (ADC_T *)dev;
00348
00349 adc->clk_cb = NULL;
00350
00351 adc->adcl = 0;
00352 adc->adch = 0;
00353 adc->adc_count = 0;
00354 adc->adc_in = 0;
00355 adc->divisor = 0;
00356 }
00357
00358
static char *
00359 adc_reg_name (VDevice *dev,
int addr)
00360 {
00361
switch (addr -
vdev_get_base (dev))
00362 {
00363
case ADC_ADCL_ADDR:
00364
return "ADCL";
00365
case ADC_ADCH_ADDR:
00366
return "ADCH";
00367
default:
00368
avr_error (
"Bad address: 0x%04x", addr);
00369 }
00370
return NULL;
00371 }
00372
00373
static int
00374 adc_clk_incr_cb (uint64_t ck, AvrClass *data)
00375 {
00376 ADC_T *adc = (ADC_T *)data;
00377 uint8_t last = adc->adc_count;
00378 ADCIntr_T *adc_ti;
00379
00380 adc_ti =
00381 (ADCIntr_T *)
avr_core_get_vdev_by_name ((AvrCore *)
00382 vdev_get_core ((VDevice *)
00383 adc),
00384
"ADCIntr");
00385
00386
if (adc->clk_cb == NULL)
00387
return CB_RET_REMOVE;
00388
00389
if (adc->divisor <= 0)
00390
avr_error (
"Bad divisor value: %d", adc->divisor);
00391
00392
00393 adc->adc_count -= ((ck % (adc->divisor * adc->u_divisor)) == 0);
00394
00395
if (adc->adc_count != last)
00396 {
00397
if (adc->adc_count == 0)
00398 {
00399 adc_ti->adcsr |= mask_ADIF;
00400 adc_ti->adcsr &= ~mask_ADSC;
00401 adc->adc_in = adc_port_rd (adc_ti->admux);
00402 adc->adcl = (adc->adc_in) & 0xff;
00403
00404 adc->adch = ((adc->adc_in) >> 8) & 0x03;
00405
if (adc_ti->adcsr & mask_ADFR)
00406 adc->adc_count = 13;
00407
else
00408 {
00409 adc->clk_cb = NULL;
00410
return CB_RET_REMOVE;
00411 }
00412 }
00413 }
00414
return CB_RET_RETAIN;
00415 }
00416
00417
00418
00419
00420 uint16_t
00421 adc_port_rd (uint8_t mux)
00422 {
00423
int data;
00424
char line[80];
00425
00426
while (1)
00427 {
00428 fprintf (stderr,
"\nEnter data to read into the ADC for channel %d: ",
00429 mux);
00430
00431
00432
if (fgets (line,
sizeof (line), stdin) == NULL)
00433
continue;
00434
00435
00436
if (sscanf (line,
"%d\n", &data) != 1)
00437
continue;
00438
00439
break;
00440 }
00441
return (uint16_t) (data & 0x3ff);
00442 }
00443
00444
void
00445 adc_port_wr (uint8_t val)
00446 {
00447 fprintf (stderr,
"wrote 0x%02x to ADC\n", val);
00448 }