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
00033
00034
00035
00036
00037 #include <config.h>
00038
00039 #include <stdio.h>
00040 #include <stdlib.h>
00041 #include <string.h>
00042
00043 #include "avrerror.h"
00044 #include "avrmalloc.h"
00045 #include "avrclass.h"
00046 #include "utils.h"
00047 #include "callback.h"
00048 #include "op_names.h"
00049
00050 #include "storage.h"
00051 #include "flash.h"
00052
00053 #include "vdevs.h"
00054 #include "memory.h"
00055 #include "stack.h"
00056 #include "register.h"
00057 #include "sram.h"
00058 #include "eeprom.h"
00059 #include "timers.h"
00060 #include "ports.h"
00061
00062 #include "avrcore.h"
00063
00064
00065
00066
00067
00068
00069
00070 static Port *port_new (int addr, char *name);
00071 static void port_construct (Port *p, int addr, char *name);
00072 static void port_destroy (void *p);
00073
00074 static uint8_t port_reg_read (VDevice *dev, int addr);
00075 static void port_reg_write (VDevice *dev, int addr, uint8_t val);
00076 static void port_reset (VDevice *dev);
00077
00078 static uint8_t port_read_pin (Port *p, int addr);
00079
00080 static void port_write_port (Port *p, int addr, uint8_t val);
00081
00082 static void port_write_ddr (Port *p, int addr, uint8_t val);
00083
00084 static void port_add_addr (VDevice *vdev, int addr, char *name, int rel_addr,
00085 void *data);
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099 VDevice *
00100 port_create (int addr, char *name, int rel_addr, void *data)
00101 {
00102 return (VDevice *)port_new (addr, name);
00103 }
00104
00105
00106
00107
00108
00109 static Port *
00110 port_new (int addr, char *name)
00111 {
00112 Port *p;
00113
00114 p = avr_new0 (Port, 1);
00115 port_construct (p, addr, name);
00116 class_overload_destroy ((AvrClass *)p, port_destroy);
00117
00118 return p;
00119 }
00120
00121
00122
00123
00124
00125 static void
00126 port_construct (Port *p, int addr, char *name)
00127 {
00128 if (p == NULL)
00129 avr_error ("passed null ptr");
00130
00131 vdev_construct ((VDevice *)p, port_reg_read, port_reg_write, port_reset,
00132 port_add_addr);
00133
00134 port_add_addr ((VDevice *)p, addr, name, 0, NULL);
00135
00136 p->ext_rd = NULL;
00137 p->ext_wr = NULL;
00138
00139 port_reset ((VDevice *)p);
00140 }
00141
00142 static void
00143 port_add_addr (VDevice *vdev, int addr, char *name, int rel_addr, void *data)
00144 {
00145 Port *p = (Port *)vdev;
00146
00147 if (strncmp ("PORT", name, 4) == 0)
00148 {
00149 p->port_addr = addr;
00150 }
00151
00152 else if (strncmp ("DDR", name, 3) == 0)
00153 {
00154 p->ddr_addr = addr;
00155 }
00156
00157 else if (strncmp ("PIN", name, 3) == 0)
00158 {
00159 p->pin_addr = addr;
00160 }
00161
00162 else
00163 {
00164 avr_error ("invalid port register name: '%s' @ 0x%04x", name, addr);
00165 }
00166 }
00167
00168 static void
00169 port_reset (VDevice *dev)
00170 {
00171 Port *p = (Port *)dev;
00172
00173 p->port = 0;
00174 p->ddr = 0;
00175 p->pin = 0;
00176
00177 p->ext_enable = 1;
00178 }
00179
00180
00181
00182
00183
00184
00185
00186 void
00187 port_destroy (void *p)
00188 {
00189 if (p == NULL)
00190 return;
00191
00192 vdev_destroy (p);
00193 }
00194
00195
00196
00197
00198
00199 void
00200 port_ext_disable (Port *p)
00201 {
00202 p->ext_enable = 0;
00203 }
00204
00205
00206
00207
00208
00209 void
00210 port_ext_enable (Port *p)
00211 {
00212 p->ext_enable = 1;
00213 }
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230 void
00231 port_add_ext_rd_wr (Port *p, PortFP_ExtRd ext_rd, PortFP_ExtWr ext_wr)
00232 {
00233 p->ext_rd = ext_rd;
00234 p->ext_wr = ext_wr;
00235 }
00236
00237 static uint8_t
00238 port_read_pin (Port *p, int addr)
00239 {
00240 uint8_t data;
00241
00242
00243 if (p->ext_rd && p->ext_enable)
00244 data = p->ext_rd (addr);
00245 else
00246 data = 0;
00247
00248
00249
00250
00251
00252 data &= ~(p->ddr);
00253
00254
00255
00256
00257
00258
00259
00260
00261 return data;
00262 }
00263
00264 static void
00265 port_write_port (Port *p, int addr, uint8_t val)
00266 {
00267
00268 p->port = val;
00269
00270
00271
00272
00273
00274 if (p->ext_wr && p->ext_enable)
00275 p->ext_wr (addr, (p->port & p->ddr));
00276 }
00277
00278 static void
00279 port_write_ddr (Port *p, int addr, uint8_t val)
00280 {
00281
00282 p->ddr = val;
00283
00284 #if 0
00285
00286
00287
00288
00289 if (p->ext_wr && p->ext_enable)
00290 p->ext_wr (addr, (p->port & p->ddr));
00291 #endif
00292 }
00293
00294 static uint8_t
00295 port_reg_read (VDevice *dev, int addr)
00296 {
00297 Port *p = (Port *)dev;
00298
00299 if (addr == p->ddr_addr)
00300 return p->ddr;
00301
00302 else if (addr == p->pin_addr)
00303 return port_read_pin (p, addr);
00304
00305 else if (addr == p->port_addr)
00306 return p->port;
00307
00308 else
00309 avr_error ("Invalid Port Address: 0x%02x", addr);
00310
00311 return 0;
00312 }
00313
00314 static void
00315 port_reg_write (VDevice *dev, int addr, uint8_t val)
00316 {
00317 Port *p = (Port *)dev;
00318
00319 if (addr == p->pin_addr)
00320 {
00321 avr_warning ("Attempt to write to readonly PINx register\n");
00322 }
00323
00324 else if (addr == p->ddr_addr)
00325 {
00326 port_write_ddr ((Port *)p, addr, val);
00327 }
00328
00329 else if (addr == p->port_addr)
00330 {
00331 port_write_port ((Port *)p, addr, val);
00332 }
00333
00334 else
00335 {
00336 avr_error ("Invalid Port Address: 0x%02x", addr);
00337 }
00338 }
00339